This file is indexed.

/usr/include/trilinos/Teuchos_RCPDecl.hpp is in libtrilinos-teuchos-dev 12.12.1-5.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
// @HEADER
// ***********************************************************************
//
//                    Teuchos: Common Tools Package
//                 Copyright (2004) Sandia Corporation
//
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
// license for use of this work by or on behalf of the U.S. Government.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
//
// ***********************************************************************
// @HEADER

#ifndef TEUCHOS_RCP_DECL_HPP
#define TEUCHOS_RCP_DECL_HPP


/*! \file Teuchos_RCPDecl.hpp
    \brief Reference-counted pointer class and non-member templated function implementations.
*/


#include "Teuchos_RCPNode.hpp"
#include "Teuchos_ENull.hpp"
#include "Teuchos_NullIteratorTraits.hpp"


#ifdef REFCOUNTPTR_INLINE_FUNCS
#  define REFCOUNTPTR_INLINE inline
#else
#  define REFCOUNTPTR_INLINE
#endif


#ifdef TEUCHOS_DEBUG
#  define TEUCHOS_REFCOUNTPTR_ASSERT_NONNULL
#endif


namespace Teuchos {


/** \brief . */
template<class T> class Ptr;


enum ERCPWeakNoDealloc { RCP_WEAK_NO_DEALLOC };
enum ERCPUndefinedWeakNoDealloc { RCP_UNDEFINED_WEAK_NO_DEALLOC };
enum ERCPUndefinedWithDealloc { RCP_UNDEFINED_WITH_DEALLOC };


/** \brief Smart reference counting pointer class for automatic garbage
  collection.

For a carefully written discussion about what this class is and basic details
on how to use it see the <A
HREF="../../../teuchos/doc/html/RefCountPtrBeginnersGuideSAND.pdf">beginners
guide</A>.

<b>Quickstart for <tt>RCP</tt></b>

Here we present a short, but fairly comprehensive, quick-start for the
use of <tt>RCP<></tt>.  The use cases described here
should cover the overwhelming majority of the use instances of
<tt>RCP<></tt> in a typical program.

The following class hierarchy will be used in the C++ examples given
below.

\code

class A { public: virtual ~A(){} virtual void f(){} };
class B1 : virtual public A {};
class B2 : virtual public A {};
class C : virtual public B1, virtual public B2 {};

class D {};
class E : public D {};

\endcode

All of the following code examples used in this quickstart are assumed to be
in the namespace <tt>Teuchos</tt> or have appropriate <tt>using
Teuchos::...</tt> declarations.  This removes the need to explicitly use
<tt>Teuchos::</tt> to qualify classes, functions and other declarations from
the <tt>Teuchos</tt> namespace.  Note that some of the runtime checks are
denoted as "debug runtime checked" which means that checking will only be
performed in a debug build (that is one where the macro <tt>TEUCHOS_DEBUG</tt>
is defined at compile time).

<ol>

<li> <b>Creation of <tt>RCP<></tt> objects</b>

<ol>

<li> <b>Creating an <tt>RCP<></tt> object using <tt>new</tt></b>

\code
RCP<C> c_ptr = rcp(new C);
\endcode

<li> <b>Creating a <tt>RCP<></tt> object equipped with a specialized
deallocator function</b> : <tt>Teuchos::DeallocFunctorDelete</tt>

\code
void someDeallocFunction(C* c_ptr);

RCP<C> c_ptr = rcp(new deallocFunctorDelete<C>(someDeallocFunction),true);
\endcode

<li> <b>Initializing a <tt>RCP<></tt> object to NULL</b>

\code
RCP<C> c_ptr;
\endcode

or

\code
RCP<C> c_ptr = null;
\endcode

<li> <b>Initializing a <tt>RCP<></tt> object to an object
       \underline{not} allocated with <tt>new</tt></b>

\code
C c;
RCP<C> c_ptr = rcpFromRef(c);
\endcode

<li> <b>Copy constructor (implicit casting)</b>

\code
RCP<C>       c_ptr  = rcp(new C); // No cast
RCP<A>       a_ptr  = c_ptr;      // Cast to base class
RCP<const A> ca_ptr = a_ptr;      // Cast from non-const to const
\endcode

<li> <b>Representing constantness and non-constantness</b>

<ol>

<li> <b>Non-constant pointer to non-constant object</b>
\code
RCP<C> c_ptr;
\endcode

<li> <b>Constant pointer to non-constant object</b>
\code
const RCP<C> c_ptr;
\endcode

<li> <b>Non-Constant pointer to constant object</b>
\code
RCP<const C> c_ptr;
\endcode

<li> <b>Constant pointer to constant object</b>
\code
const RCP<const C> c_ptr;
\endcode

</ol>

</ol>

<li> <b>Reinitialization of <tt>RCP<></tt> objects (using assignment
operator)</b>

<ol>

<li> <b>Resetting from a raw pointer</b>

\code
RCP<A> a_ptr;
a_ptr = rcp(new C());
\endcode

<li> <b>Resetting to null</b>

\code
RCP<A> a_ptr = rcp(new C());
a_ptr = null; // The C object will be deleted here
\endcode

<li> <b>Assigning from a <tt>RCP<></tt> object</b>

\code
RCP<A> a_ptr1;
RCP<A> a_ptr2 = rcp(new C());
a_ptr1 = a_ptr2; // Now a_ptr1 and a_ptr2 point to same C object
\endcode

</ol>

<li> <b>Accessing the reference-counted object</b>

<ol>

<li> <b>Access to object reference (debug runtime checked)</b> :
<tt>Teuchos::RCP::operator*()</tt>

\code
C &c_ref = *c_ptr;
\endcode

<li> <b>Access to object pointer (unchecked, may return <tt>NULL</tt>)</b> :
<tt>Teuchos::RCP::get()</tt>

\code
C *c_rptr = c_ptr.get();
\endcode

or

\code
C *c_rptr = c_ptr.getRawPtr();
\endcode

<b>WARNING:</b>: Avoid exposing raw C++ pointers!

<li> <b>Access to object pointer (debug runtime checked, will not return
<tt>NULL</tt>)</b> : <tt>Teuchos::RCP::operator*()</tt>

\code
C *c_rptr = &*c_ptr;
\endcode

<b>WARNING:</b>: Avoid exposing raw C++ pointers!

<li> <b>Access of object's member (debug runtime checked)</b> :
<tt>Teuchos::RCP::operator->()</tt>

\code
c_ptr->f();
\endcode

<li> <b>Testing for non-null</b> : <tt>Teuchos::RCP::get()</tt>,
<tt>Teuchos::operator==()</tt>, <tt>Teuchos::operator!=()</tt>

\code
if (a_ptr.is_null) std::cout << "a_ptr is not null!\n";
\endcode

or

\code
if (a_ptr != null) std::cout << "a_ptr is not null!\n";
\endcode

or

<li> <b>Testing for null</b>

\code
if (!a_ptr.is_null()) std::cout << "a_ptr is null!\n";
\endcode

or

\code
if (a_ptr == null) std::cout << "a_ptr is null!\n";
\endcode

or

\code
if (is_null(a_ptr)) std::cout << "a_ptr is null!\n";
\endcode

</ol>

<li> <b>Casting</b>

<ol>

<li> <b>Implicit casting (see copy constructor above)</b>

<ol>

<li> <b>Using copy constructor (see above)</b>

<li> <b>Using conversion function</b>

\code
RCP<C>       c_ptr  = rcp(new C);                       // No cast
RCP<A>       a_ptr  = rcp_implicit_cast<A>(c_ptr);      // To base
RCP<const A> ca_ptr = rcp_implicit_cast<const A>(a_ptr);// To const
\endcode

</ol>

<li> <b>Casting away <tt>const</tt></b> : <tt>rcp_const_cast()</tt>

\code
RCP<const A>  ca_ptr = rcp(new C);
RCP<A>        a_ptr  = rcp_const_cast<A>(ca_ptr); // cast away const!
\endcode

<li> <b>Static cast (no runtime check)</b> : <tt>rcp_static_cast()</tt>

\code
RCP<D>     d_ptr = rcp(new E);
RCP<E>     e_ptr = rcp_static_cast<E>(d_ptr); // Unchecked, unsafe?
\endcode

<li> <b>Dynamic cast (runtime checked, failed cast allowed)</b> : <tt>rcp_dynamic_cast()</tt>

\code
RCP<A>     a_ptr  = rcp(new C);
RCP<B1>    b1_ptr = rcp_dynamic_cast<B1>(a_ptr);  // Checked, safe!
RCP<B2>    b2_ptr = rcp_dynamic_cast<B2>(b1_ptr); // Checked, safe!
RCP<C>     c_ptr  = rcp_dynamic_cast<C>(b2_ptr);  // Checked, safe!
\endcode

<li> <b>Dynamic cast (runtime checked, failed cast not allowed)</b> : <tt>rcp_dynamic_cast()</tt>

\code
RCP<A>     a_ptr1  = rcp(new C);
RCP<A>     a_ptr2  = rcp(new A);
RCP<B1>    b1_ptr1 = rcp_dynamic_cast<B1>(a_ptr1, true);  // Success!
RCP<B1>    b1_ptr2 = rcp_dynamic_cast<B1>(a_ptr2, true);  // Throw std::bad_cast!
\endcode

</ol>


<li> <b>Customized deallocators</b>

<ol>

<li> <b>Creating a <tt>RCP<></tt> object with a custom deallocator</b> : <tt>rcp()</tt>

TODO: Update this example!

<li> <b>Access customized deallocator (runtime checked, throws on failure)</b> : <tt>Teuchos::get_dealloc()</tt>

\code
const MyCustomDealloc<C>
  &dealloc = get_dealloc<MyCustomDealloc<C> >(c_ptr);
\endcode

<li> <b>Access optional customized deallocator</b> : <tt>Teuchos::get_optional_dealloc()</tt>

\code
const Ptr<const MyCustomDealloc<C> > dealloc =
  get_optional_dealloc<MyCustomDealloc<C> >(c_ptr);
if (!is_null(dealloc))
  std::cout << "This deallocator exits!\n";
\endcode

</ol>

<li> <b>Managing extra data</b>

<ol>

<li> <b>Adding extra data (post destruction of extra data)</b> : <tt>Teuchos::set_extra_data()</tt>

\code
set_extra_data(rcp(new B1), "A:B1", inOutArg(a_ptr));
\endcode

<li> <b>Adding extra data (pre destruction of extra data)</b> : <tt>Teuchos::get_extra_data()</tt>

\code
set_extra_data(rcp(new B1),"A:B1", inOutArg(a_ptr), PRE_DESTORY);
\endcode

<li> <b>Retrieving extra data</b> : <tt>Teuchos::get_extra_data()</tt>

\code
get_extra_data<RCP<B1> >(a_ptr, "A:B1")->f();
\endcode

<li> <b>Resetting extra data</b> : <tt>Teuchos::get_extra_data()</tt>

\code
get_extra_data<RCP<B1> >(a_ptr, "A:B1") = rcp(new C);
\endcode

<li> <b>Retrieving optional extra data</b> : <tt>Teuchos::get_optional_extra_data()</tt>

\code
const Ptr<const RCP<B1> > b1 =
  get_optional_extra_data<RCP<B1> >(a_ptr, "A:B1");
if (!is_null(b1))
  (*b1)->f();
\endcode

</ol>

</ol>

\ingroup teuchos_mem_mng_grp

 */

template<class T>
class RCP {
public:

  /** \brief . */
  typedef T  element_type;

  /** \name Constructors/destructors/initializers. */
  //@{

  /** \brief Initialize <tt>RCP<T></tt> to NULL.
   *
   * <b>Postconditons:</b> <ul>
   * <li> <tt>this->get() == 0</tt>
   * <li> <tt>this->strength() == RCP_STRENGTH_INVALID</tt>
   * <li> <tt>this->is_vali_ptr() == true</tt>
   * <li> <tt>this->strong_count() == 0</tt>
   * <li> <tt>this->weak_count() == 0</tt>
   * <li> <tt>this->has_ownership() == false</tt>
   * </ul>
   *
   * This allows clients to write code like:
   \code
   RCP<int> p = null;
   \endcode
   or
   \code
   RCP<int> p;
   \endcode
   * and construct to <tt>NULL</tt>
   */
  inline RCP(ENull null_arg = null);

  /** \brief Construct from a raw pointer.
   *
   * Note that this constructor is declared explicit so there is no implicit
   * conversion from a raw pointer to an RCP allowed.  If
   * <tt>has_ownership==false</tt>, then no attempt to delete the object will
   * occur.
   *
   * <b>Postconditons:</b><ul>
   * <li> <tt>this->get() == p</tt>
   * <li> <tt>this->strength() == RCP_STRONG</tt>
   * <li> <tt>this->is_vali_ptr() == true</tt>
   * <li> <tt>this->strong_count() == 1</tt>
   * <li> <tt>this->weak_count() == 0</tt>
   * <li> <tt>this->has_ownership() == has_ownership</tt>
   * </ul>
   *
   * NOTE: It is recommended that this constructor never be called directly
   * but only through a type-specific non-member constructor function or at
   * least through the general non-member <tt>rcp()</tt> function.
   */
  inline explicit RCP( T* p, bool has_ownership = true );

  /** \brief Construct from a raw pointer and a custom deallocator.
   *
   * \param p [in] Pointer to the reference-counted object to be wrapped
   *
   * \param dealloc [in] Deallocator policy object that will be copied by
   * value and will perform the custom deallocation of the object pointed to
   * by <tt>p</tt> when the last <tt>RCP</tt> object goes away.  See the class
   * <tt>DeallocDelete</tt> for the specfication and behavior of this policy
   * interface.
   *
   * \post <tt>this->get() == p</tt>
   * \post <tt>this->strength() == RCP_STRONG</tt>
   * \post <tt>this->is_vali_ptr() == true</tt>
   * \post <tt>this->strong_count() == 1</tt>
   * \post <tt>this->weak_count() == 0</tt>
   * \post <tt>this->has_ownership() == has_ownership</tt>
   * \post <tt> get_dealloc<Delalloc_T>(*this) </tt> returns a copy
   *   of the custom deallocator object <tt>dealloc>/tt>.
   */
  template<class Dealloc_T>
  inline RCP(T* p, Dealloc_T dealloc, bool has_ownership);

  /** \brief Initialize from another <tt>RCP<T></tt> object.
   *
   * After construction, <tt>this</tt> and <tt>r_ptr</tt> will
   * reference the same object.
   *
   * This form of the copy constructor is required even though the
   * below more general templated version is sufficient since some
   * compilers will generate this function automatically which will
   * give an incorrect implementation.
   *
   * <b>Postconditons:</b><ul>
   * <li> <tt>this->get() == r_ptr.get()</tt>
   * <li> <tt>this->strong_count() == r_ptr.strong_count()</tt>
   * <li> <tt>this->has_ownership() == r_ptr.has_ownership()</tt>
   * <li> If <tt>r_ptr.get() != NULL</tt> then <tt>r_ptr.strong_count()</tt> is incremented by 1
   * </ul>
   */
  inline RCP(const RCP<T>& r_ptr);

  /** \brief Initialize from another <tt>RCP<T2></tt> object (implicit conversion only).
   *
   * This function allows the implicit conversion of smart pointer objects just
   * like with raw C++ pointers.  Note that this function will only compile
   * if the statement <tt>T1 *ptr = r_ptr.get()</tt> will compile.
   *
   * <b>Postconditons:</b> <ul>
   * <li> <tt>this->get() == r_ptr.get()</tt>
   * <li> <tt>this->strong_count() == r_ptr.strong_count()</tt>
   * <li> <tt>this->has_ownership() == r_ptr.has_ownership()</tt>
   * <li> If <tt>r_ptr.get() != NULL</tt> then <tt>r_ptr.strong_count()</tt> is incremented by 1
   * </ul>
   */
  template<class T2>
  inline RCP(const RCP<T2>& r_ptr);

  /** \brief Removes a reference to a dynamically allocated object and possibly deletes
   * the object if owned.
   *
   * Deletes the object if <tt>this->has_ownership() == true</tt> and
   * <tt>this->strong_count() == 1</tt>.  If <tt>this->strong_count() ==
   * 1</tt> but <tt>this->has_ownership() == false</tt> then the object is not
   * deleted.  If <tt>this->strong_count() > 1</tt> then the internal
   * reference count shared by all the other related <tt>RCP<...></tt> objects
   * for this shared object is deincremented by one.  If <tt>this->get() ==
   * NULL</tt> then nothing happens.
   */
  inline ~RCP();

  /** \brief Copy the pointer to the referenced object and increment the
   * reference count.
   *
   * If <tt>this->has_ownership() == true</tt> and <tt>this->strong_count() == 1</tt>
   * before this operation is called, then the object pointed to by
   * <tt>this->get()</tt> will be deleted (usually using <tt>delete</tt>)
   * prior to binding to the pointer (possibly <tt>NULL</tt>) pointed to in
   * <tt>r_ptr</tt>.  Assignment to self (i.e. <tt>this->get() ==
   * r_ptr.get()</tt>) is harmless and this function does nothing.
   *
   * <b>Postconditons:</b><ul>
   * <li> <tt>this->get() == r_ptr.get()</tt>
   * <li> <tt>this->strong_count() == r_ptr.strong_count()</tt>
   * <li> <tt>this->has_ownership() == r_ptr.has_ownership()</tt>
   * <li> If <tt>r_ptr.get() != NULL</tt> then <tt>r_ptr.strong_count()</tt> is incremented by 1
   * </ul>
   *
   * Provides the "strong guarantee" in a debug build!
   */
  inline RCP<T>& operator=(const RCP<T>& r_ptr);

  /** \brief Assign to null.
   *
   * If <tt>this->has_ownership() == true</tt> and <tt>this->strong_count() == 1</tt>
   * before this operation is called, then the object pointed to by
   * <tt>this->get()</tt> will be deleted (usually using <tt>delete</tt>)
   * prior to binding to the pointer (possibly <tt>NULL</tt>) pointed to in
   * <tt>r_ptr</tt>.
   *
   * <b>Postconditons:</b><ul>
   * <li> See <tt>RCP(ENull)</tt>
   * </ul>
   */
  inline RCP<T>& operator=(ENull);

  /** \brief Swap the contents with some other RCP object. */
  inline void swap(RCP<T> &r_ptr);

  //@}

  /** \name Object/Pointer Access Functions */
  //@{

  /** \brief Returns true if the underlying pointer is null. */
  inline bool is_null() const;

  /** \brief Pointer (<tt>-></tt>) access to members of underlying object.
   *
   * <b>Preconditions:</b><ul>
   * <li> <tt>this->get() != NULL</tt> (throws <tt>NullReferenceError</tt>)
   * </ul>
   */
  inline T* operator->() const;

  /** \brief Dereference the underlying object.
   *
   * <b>Preconditions:</b><ul>
   * <li> <tt>this->get() != NULL</tt> (throws <tt>NullReferenceError</tt>)
   * </ul>
   */
  inline T& operator*() const;

  /** \brief Get the raw C++ pointer to the underlying object.
   *
   * NOTE: Prefer to get the safer Ptr<T> object from <tt>this->ptr()</tt>!
   */
  inline T* get() const;

  /** \brief Get the raw C++ pointer to the underlying object.
   *
   * NOTE: Prefer to get the safer Ptr<T> object from <tt>this->ptr()</tt>!
   */
  inline T* getRawPtr() const;

  /** \brief Get a safer wrapper raw C++ pointer to the underlying object. */
  inline Ptr<T> ptr() const;

  /** \brief Shorthand for ptr(). */
  inline Ptr<T> operator()() const;

  /** \brief Return an RCP<const T> version of *this. */
  inline RCP<const T> getConst() const;

  //@}

  /** \name Reference counting */
  //@{

  /** \brief Strength of the pointer.
   *
   * Return values:<ul>
   * <li><tt>RCP_STRONG</tt>: Underlying reference-counted object will be deleted
   *     when <tt>*this</tt> is destroyed if <tt>strong_count()==1</tt>.
   * <li><tt>RCP_WEAK</tt>: Underlying reference-counted object will not be deleted
   *     when <tt>*this</tt> is destroyed if <tt>strong_count() > 0</tt>.
   * <li><tt>RCP_STRENGTH_INVALID</tt>: <tt>*this</tt> is not strong or weak but
   *     is null.
   * </ul>
   */
  inline ERCPStrength strength() const;

  /** \brief Return if the underlying object pointer is still valid or not.
   *
   * The underlying object will not be valid if the strong count has gone to
   * zero but the weak count thas not.
   *
   * NOTE: Null is a valid object pointer.  If you want to know if there is a
   * non-null object and it is valid then <tt>!is_null() &&
   * is_valid_ptr()</tt> will be <tt>true</tt>.
   */
  inline bool is_valid_ptr() const;

  /** \brief Return the number of active <tt>RCP<></tt> objects that have a
   * "strong" reference to the underlying reference-counted object.
   *
   * \return If <tt>this->get() == NULL</tt> then this function returns 0.
   */
  inline int strong_count() const;

  /** \brief Return the number of active <tt>RCP<></tt> objects that have a
   * "weak" reference to the underlying reference-counted object.
   *
   * \return If <tt>this->get() == NULL</tt> then this function returns 0.
   */
  inline int weak_count() const;

  /** \brief Total count (strong_count() + weak_count()). */
  inline int total_count() const;

  /** \brief Give <tt>this</tt> and other <tt>RCP<></tt> objects ownership
   * of the referenced object <tt>this->get()</tt>.
   *
   * See ~RCP() above.  This function
   * does nothing if <tt>this->get() == NULL</tt>.
   *
   * <b>Postconditions:</b>
   * <ul>
   * <li> If <tt>this->get() == NULL</tt> then
   *   <ul>
   *   <li> <tt>this->has_ownership() == false</tt> (always!).
   *   </ul>
   * <li> else
   *   <ul>
   *   <li> <tt>this->has_ownership() == true</tt>
   *   </ul>
   * </ul>
   */
  inline void set_has_ownership();

  /** \brief Returns true if <tt>this</tt> has ownership of object pointed to
   * by <tt>this->get()</tt> in order to delete it.
   *
   * See ~RCP() above.
   *
   * \return If this->get() <tt>== NULL</tt> then this function always returns
   * <tt>false</tt>.  Otherwise the value returned from this function depends
   * on which function was called most recently, if any; set_has_ownership()
   * (<tt>true</tt>) or release() (<tt>false</tt>).
   */
  inline bool has_ownership() const;

  /** \brief Release the ownership of the underlying dynamically allocated
   * object.
   *
   * <b>WARNING!</b> Never call <tt>delete rcp.release().get()</tt> as this
   * can cause all kinds of segfaults.  Instead, release your use of the
   * shared object by simply assigning the <tt>RCP</tt> object to
   * <tt>Teuchos::null</tt>.
   *
   * This function should only be used as last result when all hell has broken
   * loose and memory management control has broken down.  This function is
   * not to be used lightly!
   *
   * After this function is called then the client is responsible for
   * deallocating the shared object no matter how many
   * <tt>ref_count_prt<T></tt> objects have a reference to it.  If
   * <tt>this-></tt>get()<tt>== NULL</tt>, then this call is meaningless.
   *
   * Note that this function does not have the exact same semantics as does
   * <tt>auto_ptr<T>::release()</tt>.  In <tt>auto_ptr<T>::release()</tt>,
   * <tt>this</tt> is set to <tt>NULL</tt> while here in RCP<T>::
   * release() only an ownership flag is set and <tt>*this</tt> still points
   * to the same object.  It would be difficult to duplicate the behavior of
   * <tt>auto_ptr<T>::release()</tt> for this class.
   *
   * <b>Postconditions:</b>
   * <ul>
   * <li> <tt>this->has_ownership() == false</tt>
   * </ul>
   *
   * @return Returns the value of <tt>this->get()</tt>
   */
  inline Ptr<T> release();

  /** \brief Create a new weak RCP object from another (strong) RCP object.
   *
   * ToDo: Explain this!
   *
   * <b>Preconditons:</b> <ul>
   * <li> <tt>returnVal.is_valid_ptr()==true</tt>
   * </ul>
   *
   * <b>Postconditons:</b> <ul>
   * <li> <tt>returnVal.get() == this->get()</tt>
   * <li> <tt>returnVal.strong_count() == this->strong_count()</tt>
   * <li> <tt>returnVal.weak_count() == this->weak_count()+1</tt>
   * <li> <tt>returnVal.strength() == RCP_WEAK</tt>
   * <li> <tt>returnVal.has_ownership() == this->has_ownership()</tt>
   * </ul>
   */
  inline RCP<T> create_weak() const;

  /** \brief Create a new strong RCP object from another (weak) RCP object.
   *
   * ToDo: Explain this!
   *
   * <b>Preconditons:</b> <ul>
   * <li> <tt>returnVal.is_valid_ptr()==true</tt>
   * </ul>
   *
   * <b>Postconditons:</b> <ul>
   * <li> <tt>returnVal.get() == this->get()</tt>
   * <li> <tt>returnVal.strong_count() == this->strong_count() + 1</tt>
   * <li> <tt>returnVal.weak_count() == this->weak_count()</tt>
   * <li> <tt>returnVal.strength() == RCP_STRONG</tt>
   * <li> <tt>returnVal.has_ownership() == this->has_ownership()</tt>
   * </ul>
   */
  inline RCP<T> create_strong() const;

  /** \brief Returns true if the smart pointers share the same underlying
   * reference-counted object.
   *
   * This method does more than just check if <tt>this->get() == r_ptr.get()</tt>.
   * It also checks to see if the underlying reference counting machinary is the
   * same.
   */
  template<class T2>
  inline bool shares_resource(const RCP<T2>& r_ptr) const;

  //@}

  /** \name Assertions */
  //@{

  /** \brief Throws <tt>NullReferenceError</tt> if <tt>this->get()==NULL</tt>,
   * otherwise returns reference to <tt>*this</tt>.
   */
  inline const RCP<T>& assert_not_null() const;

  /** \brief If the object pointer is non-null, assert that it is still valid.
   *
   * If <tt>is_null()==false && strong_count()==0</tt>, this will throw
   * <tt>DanglingReferenceErorr</tt> with a great error message.
   *
   * If <tt>is_null()==true</tt>, then this will not throw any exception.
   *
   * In this context, null is a valid object.
   */
  inline const RCP<T>& assert_valid_ptr() const;

  /** \brief Calls <tt>assert_not_null()</tt> in a debug build. */
  inline const RCP<T>& debug_assert_not_null() const
    {
#ifdef TEUCHOS_REFCOUNTPTR_ASSERT_NONNULL
      assert_not_null();
#endif
      return *this;
    }

  /** \brief Calls <tt>assert_valid_ptr()</tt> in a debug build. */
  inline const RCP<T>& debug_assert_valid_ptr() const
    {
#ifdef TEUCHOS_DEBUG
      assert_valid_ptr();
#endif
      return *this;
    }

  //@}

  /** \name boost::shared_ptr compatiblity funtions. */
  //@{

  /** \brief Reset to null. */
  inline void reset();

  /** \brief Reset the raw pointer with default ownership to delete.
   *
   * Equivalent to calling:

   \code

     r_rcp = rcp(p)

   \endcode
   */
  template<class T2>
  inline void reset(T2* p, bool has_ownership = true);

  /** \brief Returns <tt>strong_count()</tt> [deprecated]. */
  TEUCHOS_DEPRECATED inline int count() const;

  //@}

private:

  // //////////////////////////////////////////////////////////////
  // Private data members

  T *ptr_; // NULL if this pointer is null
  RCPNodeHandle node_; // NULL if this pointer is null

public: // Bad bad bad

  // These constructors are put here because we don't want to confuse users
  // who would otherwise see them.

  /** \brief Construct a non-owning RCP from a raw pointer to a type that *is*
   * defined.
   *
   * This version avoids adding a deallocator but still requires the type to
   * be defined since it looks up the base object's address when doing RCPNode
   * tracing.
   *
   * NOTE: It is recommended that this constructor never be called directly
   * but only through a type-specific non-member constructor function or at
   * least through the general non-member <tt>rcpFromRef()</tt> function.
   */
  inline explicit RCP(T* p, ERCPWeakNoDealloc);

  /** \brief Construct a non-owning RCP from a raw pointer to a type that is
   * *not* defined.
   *
   * This version avoids any type of compile-time queries of the type that
   * would fail due to the type being undefined.
   *
   * NOTE: It is recommended that this constructor never be called directly
   * but only through a type-specific non-member constructor function or at
   * least through the general non-member <tt>rcpFromUndefRef()</tt> function.
   */
  inline explicit RCP(T* p, ERCPUndefinedWeakNoDealloc);

  /** \brief Construct from a raw pointer and a custom deallocator for an
   * undefined type.
   *
   * This version avoids any type of compile-time queries of the type that
   * would fail due to the type being undefined.
   */
  template<class Dealloc_T>
  inline RCP(T* p, Dealloc_T dealloc, ERCPUndefinedWithDealloc,
    bool has_ownership = true);

#ifndef DOXYGEN_COMPILE

  // WARNING: A general user should *never* call these functions!
  inline RCP(T* p, const RCPNodeHandle &node);
  inline T* access_private_ptr() const; // Does not throw
  inline RCPNodeHandle& nonconst_access_private_node(); // Does not thorw
  inline const RCPNodeHandle& access_private_node() const; // Does not thorw

#endif

};

/** \brief Struct for comparing two RCPs. Simply compares
* the raw pointers contained within the RCPs*/
struct RCPComp {
  /** \brief . */
  template<class T1, class T2> inline
  bool operator() (const RCP<T1> p1, const RCP<T2> p2) const{
    return p1.get() < p2.get();
  }
};

/** \brief Struct for comparing two RCPs. Simply compares
* the raw pointers contained within the RCPs*/
struct RCPConstComp {
  /** \brief . */
  template<class T1, class T2> inline
  bool operator() (const RCP<const T1> p1, const RCP<const T2> p2) const{
    return p1.get() < p2.get();
  }
};



// 2008/09/22: rabartl: NOTE: I removed the TypeNameTraits<RCP<T> >
// specialization since I want to be able to print the type name of an RCP
// that does not have the type T fully defined!


/** \brief Traits specialization for RCP.
 *
 * \ingroup teuchos_mem_mng_grp
 */
template<typename T>
class NullIteratorTraits<RCP<T> > {
public:
  static RCP<T> getNull() { return null; }
};


/** \brief Policy class for deallocator for non-owned RCPs.
 *
 * \ingroup teuchos_mem_mng_grp
 */
template<class T>
class DeallocNull
{
public:
  /// Gives the type (required)
  typedef T ptr_t;
  /// Deallocates a pointer <tt>ptr</tt> using <tt>delete ptr</tt> (required).
  void free( T* ptr ) {
    (void) ptr; // silence "unused parameter" compiler warning
  }
};


/** \brief Policy class for deallocator that uses <tt>delete</tt> to delete a
 * pointer which is used by <tt>RCP</tt>.
 *
 * \ingroup teuchos_mem_mng_grp
 */
template<class T>
class DeallocDelete
{
public:
  /// Gives the type (required)
  typedef T ptr_t;
  /// Deallocates a pointer <tt>ptr</tt> using <tt>delete ptr</tt> (required).
  void free( T* ptr ) { if(ptr) delete ptr; }
};


/** \brief Deallocator class that uses <tt>delete []</tt> to delete memory
 * allocated uisng <tt>new []</tt>
 *
 * \ingroup teuchos_mem_mng_grp
 */
template<class T>
class DeallocArrayDelete
{
public:
  /// Gives the type (required)
  typedef T ptr_t;
  /// Deallocates a pointer <tt>ptr</tt> using <tt>delete [] ptr</tt> (required).
  void free( T* ptr ) { if(ptr) delete [] ptr; }
};


/** \brief Deallocator subclass that Allows any functor object (including a
 * function pointer) to be used to free an object.
 *
 * Note, the only requirement is that deleteFuctor(ptr) can be called (which
 * is true for a function pointer).
 *
 * Note, a client should generally use the function
 * <tt>deallocFunctorDelete()</tt> to create this object and not try to
 * construct it directly.
 *
 * \ingroup teuchos_mem_mng_grp
 */
template<class T, class DeleteFunctor>
class DeallocFunctorDelete
{
public:
  DeallocFunctorDelete( DeleteFunctor deleteFunctor ) : deleteFunctor_(deleteFunctor) {}
  typedef T ptr_t;
  void free( T* ptr ) { if(ptr) deleteFunctor_(ptr); }
private:
  DeleteFunctor deleteFunctor_;
  DeallocFunctorDelete(); // Not defined and not to be called!
};


/** \brief A simple function used to create a functor deallocator object.
 *
 * \relates DeallocFunctorDelete
 */
template<class T, class DeleteFunctor>
DeallocFunctorDelete<T,DeleteFunctor>
deallocFunctorDelete( DeleteFunctor deleteFunctor )
{
  return DeallocFunctorDelete<T,DeleteFunctor>(deleteFunctor);
}


/** \brief Deallocator subclass that Allows any functor object (including a
 * function pointer) to be used to free a handle (i.e. pointer to pointer) to
 * an object.
 *
 * Note, the only requirement is that deleteFuctor(ptrptr) can be called
 * (which is true for a function pointer).
 *
 * Note, a client should generally use the function
 * <tt>deallocFunctorDelete()</tt> to create this object and not try to
 * construct it directly.
 *
 * \ingroup teuchos_mem_mng_grp
 */
template<class T, class DeleteHandleFunctor>
class DeallocFunctorHandleDelete
{
public:
  DeallocFunctorHandleDelete( DeleteHandleFunctor deleteHandleFunctor )
    : deleteHandleFunctor_(deleteHandleFunctor) {}
  typedef T ptr_t;
  void free( T* ptr ) { if(ptr) { T **hdl = &ptr; deleteHandleFunctor_(hdl); } }
private:
  DeleteHandleFunctor deleteHandleFunctor_;
  DeallocFunctorHandleDelete(); // Not defined and not to be called!
};


/** \brief A simple function used to create a functor deallocator object.
 *
 * \relates DeallocFunctorHandleDelete
 */
template<class T, class DeleteHandleFunctor>
DeallocFunctorHandleDelete<T,DeleteHandleFunctor>
deallocFunctorHandleDelete( DeleteHandleFunctor deleteHandleFunctor )
{
  return DeallocFunctorHandleDelete<T,DeleteHandleFunctor>(deleteHandleFunctor);
}


/** \brief A deallocator class that wraps a simple value object and delegates
 * to another deallocator object.
 *
 * The type <tt>Embedded</tt> must be a true value object with a default
 * constructor, a copy constructor, and an assignment operator.
 *
 * \ingroup teuchos_mem_mng_grp
 */
template<class T, class Embedded, class Dealloc>
class EmbeddedObjDealloc
{
public:
  typedef typename Dealloc::ptr_t ptr_t;
  EmbeddedObjDealloc(
    const Embedded &embedded, EPrePostDestruction prePostDestroy,
    Dealloc dealloc
    ) : embedded_(embedded), prePostDestroy_(prePostDestroy), dealloc_(dealloc)
    {}
  void setObj( const Embedded &embedded ) { embedded_ = embedded; }
  const Embedded& getObj() const { return embedded_; }
  Embedded& getNonconstObj() { return embedded_; }
  void free( T* ptr )
    {
      if (prePostDestroy_ == PRE_DESTROY)
        embedded_ = Embedded();
      dealloc_.free(ptr);
      if (prePostDestroy_ == POST_DESTROY)
        embedded_ = Embedded();
    }
private:
  Embedded embedded_;
  EPrePostDestruction prePostDestroy_;
  Dealloc dealloc_;
  EmbeddedObjDealloc(); // Not defined and not to be called!
};


/** \brief Create a dealocator with an embedded object using delete.
 *
 * \relates EmbeddedObjDealloc
 */
template<class T, class Embedded >
EmbeddedObjDealloc<T,Embedded,DeallocDelete<T> >
embeddedObjDeallocDelete(const Embedded &embedded, EPrePostDestruction prePostDestroy)
{
  return EmbeddedObjDealloc<T,Embedded,DeallocDelete<T> >(
    embedded, prePostDestroy,DeallocDelete<T>());
}


/** \brief Create a dealocator with an embedded object using delete [].
 *
 * \relates EmbeddedObjDealloc
 */
template<class T, class Embedded >
EmbeddedObjDealloc<T,Embedded,DeallocArrayDelete<T> >
embeddedObjDeallocArrayDelete(const Embedded &embedded, EPrePostDestruction prePostDestroy)
{
  return EmbeddedObjDealloc<T,Embedded,DeallocArrayDelete<T> >(
    embedded, prePostDestroy,DeallocArrayDelete<T>());
}


/** \brief Create a <tt>RCP</tt> object properly typed.
 *
 * \param p [in] Pointer to an object to be reference counted.
 *
 * \param owns_mem [in] If <tt>owns_mem==true</tt> then <tt>delete p</tt> will
 * be called when the last reference to this object is removed.  If
 * <tt>owns_mem==false</tt> then nothing will happen to delete the the object
 * pointed to by <tt>p</tt> when the last reference is removed.
 *
 * <b>Preconditions:</b><ul>
 * <li> If <tt>owns_mem==true</tt> then <tt>p</tt> must have been
 *      created by calling <tt>new</tt> to create the object since
 *      <tt>delete p</tt> will be called eventually.
 * </ul>
 *
 * If the pointer <tt>p</tt> did not come from <tt>new</tt> then
 * either the client should use the version of <tt>rcp()</tt> that
 * that uses a deallocator policy object or should pass in
 * <tt>owns_mem = false</tt>.
 *
 * \relates RCP
 */
template<class T> inline
RCP<T> rcp(T* p, bool owns_mem = true);


/** \brief Initialize from a raw pointer with a deallocation policy.
 *
 * \param p [in] Raw C++ pointer that \c this will represent.
 *
 * \param dealloc [in] Deallocator policy object (copied by value) that
 * defines a function <tt>void Dealloc_T::free(T* p)</tt> that will free the
 * underlying object.
 *
 * \param owns_mem [in] If true then <tt>return</tt> is allowed to delete the
 * underlying pointer by calling <tt>dealloc.free(p)</tt>.  when all
 * references have been removed.
 *
 * <b>Preconditions:</b><ul>
 * <li> The function <tt>void Dealloc_T::free(T* p)</tt> exists.
 * </ul>
 *
 * <b>Postconditions:</b><ul>
 * <li> <tt>return.get() == p</tt>
 * <li> If <tt>p == NULL</tt> then
 *   <ul>
 *   <li> <tt>return.count() == 0</tt>
 *   <li> <tt>return.has_ownership() == false</tt>
 *   </ul>
 * <li> else
 *   <ul>
 *   <li> <tt>return.count() == 1</tt>
 *   <li> <tt>return.has_ownership() == owns_mem</tt>
 *   </ul>
 * </ul>
 *
 * By default, <tt>return</tt> has ownership to delete the object
 * pointed to by <tt>p</tt> when <tt>return</tt> is deleted (see
 * <tt>~RCP())</tt>.  If <tt>owns_mem==true</tt>, it is vital
 * that the address <tt>p</tt>
 * passed in is the same address that was returned by <tt>new</tt>.
 * With multiple inheritance this is not always the case.  See the
 * above discussion.  This class is templated to accept a deallocator
 * object that will free the pointer.  The other functions use a
 * default deallocator of type <tt>DeallocDelete</tt> which has a method
 * <tt>DeallocDelete::free()</tt> which just calls <tt>delete p</tt>.
 *
 * \relates RCP
 */
template<class T, class Dealloc_T> inline
RCP<T> rcpWithDealloc(T* p, Dealloc_T dealloc, bool owns_mem=true);


/** \brief Deprecated. */
template<class T, class Dealloc_T> inline
TEUCHOS_DEPRECATED RCP<T> rcp( T* p, Dealloc_T dealloc, bool owns_mem )
{
  return rcpWithDealloc(p, dealloc, owns_mem);
}


/** \brief Initialize from a raw pointer with a deallocation policy for an
 * undefined type.
 *
 * \param p [in] Raw C++ pointer that \c this will represent.
 *
 * \param dealloc [in] Deallocator policy object (copied by value) that
 * defines a function <tt>void Dealloc_T::free(T* p)</tt> that will free the
 * underlying object.
 *
 * \relates RCP
 */
template<class T, class Dealloc_T> inline
RCP<T> rcpWithDeallocUndef(T* p, Dealloc_T dealloc, bool owns_mem=true);


/** \brief Return a non-owning weak RCP object from a raw object reference for
 * a defined type.
 *
 * NOTE: When debug mode is turned on, in general, the type must be defined.
 * If the type is undefined, then the function <tt>rcpFromUndefRef()</tt>
 * should be called instead.
 *
 * \relates RCP
 */
template<class T> inline
RCP<T> rcpFromRef(T& r);


/** \brief Return a non-owning weak RCP object from a raw object reference for
 * an undefined type.
 *
 * NOTE: This version will not be able to use RCPNode tracing to create a weak
 * reference to an existing RCPNode.  Therefore, you should only use this
 * version with an undefined type.
 *
 * \relates RCP
 */
template<class T> inline
RCP<T> rcpFromUndefRef(T& r);


/** \brief Create an RCP with and also put in an embedded object.
 *
 * In this case the embedded object is destroyed (by setting to Embedded())
 * before the object at <tt>*p</tt> is destroyed.
 *
 * The embedded object can be extracted using <tt>getEmbeddedObj()</tt> and
 * <tt>getNonconstEmbeddedObject()</tt>.
 *
 * \relates RCP
 */
template<class T, class Embedded> inline
RCP<T>
rcpWithEmbeddedObjPreDestroy( T* p, const Embedded &embedded, bool owns_mem = true );


/** \brief Create an RCP with and also put in an embedded object.
 *
 * In this case the embedded object is destroyed (by setting to Embedded())
 * after the object at <tt>*p</tt> is destroyed.
 *
 * The embedded object can be extracted using <tt>getEmbeddedObj()</tt> and
 * <tt>getNonconstEmbeddedObject()</tt>.
 *
 * \relates RCP
 */
template<class T, class Embedded> inline
RCP<T>
rcpWithEmbeddedObjPostDestroy( T* p, const Embedded &embedded, bool owns_mem = true );


/** \brief Create an RCP with and also put in an embedded object.
 *
 * This function should be called when it is not important when the embedded
 * object is destroyed (by setting to Embedded()) with respect to when
 * <tt>*p</tt> is destroyed.
 *
 * The embedded object can be extracted using <tt>getEmbeddedObj()</tt> and
 * <tt>getNonconstEmbeddedObject()</tt>.
 *
 * \relates RCP
 */
template<class T, class Embedded> inline
RCP<T>
rcpWithEmbeddedObj( T* p, const Embedded &embedded, bool owns_mem = true );


// 2007/10/25: rabartl: ToDo: put in versions of
// rcpWithEmbedded[Pre,Post]DestoryWithDealloc(...) that also accept a general
// deallocator!


/** \brief Create a new RCP that inverts the ownership of parent and child.
 *
 * This implements the "inverted object ownership" idiom.
 *
 * NOTE: The parent can be retrieved using the function
 * <tt>getInvertedObjOwnershipParent(...)</tt>.
 *
 * \relates RCP
 */
template<class T, class ParentT>
RCP<T> rcpWithInvertedObjOwnership(const RCP<T> &child, const RCP<ParentT> &parent);


/** \brief Allocate a new RCP object with a new RCPNode with memory pointing
 * to the initial node.
 *
 * The purpose of this function is to create a new "handle" to the underlying
 * memory with its own seprate reference count.  The new RCP object will have
 * a new RCPNodeTmpl object that has a copy of the input RCP object embedded
 * in it.  This maintains the correct reference counting behaviors but now
 * gives a private count.  One would want to use rcpCloneNode(...) whenever it
 * is important to keep a private reference count which is needed for some
 * types of use cases.
 *
 * \relates RCP
 */
template<class T>
RCP<T> rcpCloneNode(const RCP<T> &p);


/** \brief Returns true if <tt>p.get()==NULL</tt>.
 *
 * \relates RCP
 */
template<class T> inline
bool is_null( const RCP<T> &p );


/** \brief Returns true if <tt>p.get()!=NULL</tt>.
 *
 * \relates RCP
 */
template<class T> inline
bool nonnull( const RCP<T> &p );


/** \brief Returns true if <tt>p.get()==NULL</tt>.
 *
 * \relates RCP
 */
template<class T> inline
bool operator==( const RCP<T> &p, ENull );


/** \brief Returns true if <tt>p.get()!=NULL</tt>.
 *
 * \relates RCP
 */
template<class T> inline
bool operator!=( const RCP<T> &p, ENull );


/** \brief Return true if two <tt>RCP</tt> objects point to the same
 * referenced-counted object and have the same node.
 *
 * \relates RCP
 */
template<class T1, class T2> inline
bool operator==( const RCP<T1> &p1, const RCP<T2> &p2 );


/** \brief Return true if two <tt>RCP</tt> objects do not point to the
 * same referenced-counted object and have the same node.
 *
 * \relates RCP
 */
template<class T1, class T2> inline
bool operator!=( const RCP<T1> &p1, const RCP<T2> &p2 );


/** \brief Implicit cast of underlying <tt>RCP</tt> type from <tt>T1*</tt> to <tt>T2*</tt>.
 *
 * The function will compile only if (<tt>T2* p2 = p1.get();</tt>) compiles.
 *
 * This is to be used for conversions up an inheritance hierarchy and from non-const to
 * const and any other standard implicit pointer conversions allowed by C++.
 *
 * \relates RCP
 */
template<class T2, class T1> inline
RCP<T2> rcp_implicit_cast(const RCP<T1>& p1);


/** \brief Static cast of underlying <tt>RCP</tt> type from <tt>T1*</tt> to <tt>T2*</tt>.
 *
 * The function will compile only if (<tt>static_cast<T2*>(p1.get());</tt>) compiles.
 *
 * This can safely be used for conversion down an inheritance hierarchy
 * with polymorphic types only if <tt>dynamic_cast<T2>(p1.get()) == static_cast<T2>(p1.get())</tt>.
 * If not then you have to use <tt>rcp_dynamic_cast<tt><T2>(p1)</tt>.
 *
 * \relates RCP
 */
template<class T2, class T1> inline
RCP<T2> rcp_static_cast(const RCP<T1>& p1);


/** \brief Constant cast of underlying <tt>RCP</tt> type from <tt>T1*</tt> to <tt>T2*</tt>.
 *
 * This function will compile only if (<tt>const_cast<T2*>(p1.get());</tt>) compiles.
 *
 * \relates RCP
 */
template<class T2, class T1> inline
RCP<T2> rcp_const_cast(const RCP<T1>& p1);


/** \brief Dynamic cast of underlying <tt>RCP</tt> type from <tt>T1*</tt> to <tt>T2*</tt>.
 *
 * \param p1 [in] The smart pointer casting from
 *
 * \param throw_on_fail [in] If <tt>true</tt> then if the cast fails (for
 * <tt>p1.get()!=NULL) then a <tt>std::bad_cast</tt> std::exception is thrown
 * with a very informative error message.
 *
 * <b>Postconditions:</b><ul>
 * <li> If <tt>( p1.get()!=NULL && throw_on_fail==true && dynamic_cast<T2*>(p1.get())==NULL ) == true</tt>
 *      then an <tt>std::bad_cast</tt> std::exception is thrown with a very informative error message.
 * <li> If <tt>( p1.get()!=NULL && dynamic_cast<T2*>(p1.get())!=NULL ) == true</tt>
 *      then <tt>return.get() == dynamic_cast<T2*>(p1.get())</tt>.
 * <li> If <tt>( p1.get()!=NULL && throw_on_fail==false && dynamic_cast<T2*>(p1.get())==NULL ) == true</tt>
 *      then <tt>return.get() == NULL</tt>.
 * <li> If <tt>( p1.get()==NULL ) == true</tt>
 *      then <tt>return.get() == NULL</tt>.
 * </ul>
 *
 * This function will compile only if (<tt>dynamic_cast<T2*>(p1.get());</tt>) compiles.
 *
 * \relates RCP
 */
template<class T2, class T1> inline
RCP<T2> rcp_dynamic_cast(
  const RCP<T1>& p1, bool throw_on_fail = false
  );


/** \brief Set extra data associated with a <tt>RCP</tt> object.
 *
 * \param extra_data [in] Data object that will be set (copied)
 *
 * \param name [in] The name given to the extra data.  The value of
 * <tt>name</tt> together with the data type <tt>T1</tt> of the extra data
 * must be unique from any other such data or the other data will be
 * overwritten.
 *
 * \param p [out] On output, will be updated with the input
 * <tt>extra_data</tt>
 *
 * \param destroy_when [in] Determines when <tt>extra_data</tt> will be
 * destroyed in relation to the underlying reference-counted object.  If
 * <tt>destroy_when==PRE_DESTROY</tt> then <tt>extra_data</tt> will be deleted
 * before the underlying reference-counted object.  If
 * <tt>destroy_when==POST_DESTROY</tt> (the default) then <tt>extra_data</tt>
 * will be deleted after the underlying reference-counted object.
 *
 * \param force_unique [in] Determines if this type and name pair must be
 * unique in which case if an object with this same type and name already
 * exists, then an std::exception will be thrown.  The default is
 * <tt>true</tt> for safety.
 *
 * If there is a call to this function with the same type of extra
 * data <tt>T1</tt> and same arguments <tt>p</tt> and <tt>name</tt>
 * has already been made, then the current piece of extra data already
 * set will be overwritten with <tt>extra_data</tt>.  However, if the
 * type of the extra data <tt>T1</tt> is different, then the extra
 * data can be added and not overwrite existing extra data.  This
 * means that extra data is keyed on both the type and name.  This
 * helps to minimize the chance that clients will unexpectedly
 * overwrite data by accident.
 *
 * When the last <tt>RefcountPtr</tt> object is removed and the
 * reference-count node is deleted, then objects are deleted in the following
 * order: (1) All of the extra data that where added with
 * <tt>destroy_when==PRE_DESTROY</tt> are first, (2) then the underlying
 * reference-counted object is deleted, and (3) the rest of the extra data
 * that was added with <tt>destroy_when==PRE_DESTROY</tt> is then deleted.
 * The order in which the objects are destroyed is not guaranteed.  Therefore,
 * clients should be careful not to add extra data that has deletion
 * dependancies (instead consider using nested RCP objects as extra
 * data which will guarantee the order of deletion).
 *
 * <b>Preconditions:</b><ul>
 * <li> <tt>p->get() != NULL</tt> (throws <tt>NullReferenceError</tt>)
 * <li> If this function has already been called with the same template
 *      type <tt>T1</tt> for <tt>extra_data</tt> and the same std::string <tt>name</tt>
 *      and <tt>force_unique==true</tt>, then an <tt>std::invalid_argument</tt>
 *      std::exception will be thrown.
 * </ul>
 *
 * Note, this function is made a non-member function to be consistent
 * with the non-member <tt>get_extra_data()</tt> functions.
 *
 * \relates RCP
 */
template<class T1, class T2>
void set_extra_data( const T1 &extra_data, const std::string& name,
  const Ptr<RCP<T2> > &p, EPrePostDestruction destroy_when = POST_DESTROY,
  bool force_unique = true);

/** \brief Get a const reference to extra data associated with a <tt>RCP</tt> object.
 *
 * \param p [in] Smart pointer object that extra data is being extraced from.
 *
 * \param name [in] Name of the extra data.
 *
 * @return Returns a const reference to the extra_data object.
 *
 * <b>Preconditions:</b><ul>
 * <li> <tt>p.get() != NULL</tt> (throws <tt>NullReferenceError</tt>)
 * <li> <tt>name</tt> and <tt>T1</tt> must have been used in a previous
 *      call to <tt>set_extra_data()</tt> (throws <tt>std::invalid_argument</tt>).
 * </ul>
 *
 * Note, this function must be a non-member function since the client
 * must manually select the first template argument.
 *
 * \relates RCP
 */
template<class T1, class T2>
const T1& get_extra_data( const RCP<T2>& p, const std::string& name );


/** \brief Get a non-const reference to extra data associated with a <tt>RCP</tt> object.
 *
 * \param p [in] Smart pointer object that extra data is being extraced from.
 *
 * \param name [in] Name of the extra data.
 *
 * @return Returns a non-const reference to the extra_data object.
 *
 * <b>Preconditions:</b><ul>
 * <li> <tt>p.get() != NULL</tt> (throws <tt>NullReferenceError</tt>)
 * <li> <tt>name</tt> and <tt>T1</tt> must have been used in a previous
 *      call to <tt>set_extra_data()</tt> (throws <tt>std::invalid_argument</tt>).
 * </ul>
 *
 * Note, this function must be a non-member function since the client
 * must manually select the first template argument.
 *
 * \relates RCP
 */
template<class T1, class T2>
T1& get_nonconst_extra_data( RCP<T2>& p, const std::string& name );


/** \brief Get a pointer to const extra data (if it exists) associated with a
 * <tt>RCP</tt> object.
 *
 * \param p [in] Smart pointer object that extra data is being extraced from.
 *
 * \param name [in] Name of the extra data.
 *
 * @return Returns a const pointer to the extra_data object if it exists.
 *
 * <b>Preconditions:</b><ul>
 * <li> <tt>p.get() != NULL</tt> (throws <tt>NullReferenceError</tt>)
 * </ul>
 *
 * <b>Postconditions:</b><ul>
 * <li> If <tt>name</tt> and <tt>T1</tt> have been used in a previous
 *      call to <tt>set_extra_data()</tt> then <tt>return !=NULL</tt>
 *      and otherwise <tt>return == NULL</tt>.
 * </ul>
 *
 * Note, this function must be a non-member function since the client
 * must manually select the first template argument.
 *
 * \relates RCP
 */
template<class T1, class T2>
Ptr<const T1> get_optional_extra_data( const RCP<T2>& p, const std::string& name );


/** \brief Get a pointer to non-const extra data (if it exists) associated
 * with a <tt>RCP</tt> object.
 *
 * \param p [in] Smart pointer object that extra data is being extraced from.
 *
 * \param name [in] Name of the extra data.
 *
 * @return Returns a non-const pointer to the extra_data object.
 *
 * <b>Preconditions:</b><ul>
 * <li> <tt>p.get() != NULL</tt> (throws <tt>NullReferenceError</tt>)
 * </ul>
 *
 * <b>Postconditions:</b><ul>
 * <li> If <tt>name</tt> and <tt>T1</tt> have been used in a previous
 *      call to <tt>set_extra_data()</tt> then <tt>return !=NULL</tt>
 *      and otherwise <tt>return == NULL</tt>.
 * </ul>
 *
 * Note, this function must be a non-member function since the client
 * must manually select the first template argument.
 *
 * \relates RCP
 */
template<class T1, class T2>
Ptr<T1> get_optional_nonconst_extra_data( RCP<T2>& p, const std::string& name );


/** \brief Return a <tt>const</tt> reference to the underlying deallocator
 * object.
 *
 * <b>Preconditions:</b><ul>
 * <li> <tt>p.get() != NULL</tt> (throws <tt>NullReferenceError</tt>)
 * <li> The deallocator object type used to construct <tt>p</tt> is same as <tt>Dealloc_T</tt>
 *      (throws <tt>NullReferenceError</tt>)
 * </ul>
 *
 * \relates RCP
 */
template<class Dealloc_T, class T>
const Dealloc_T& get_dealloc( const RCP<T>& p );


/** \brief Return a non-<tt>const</tt> reference to the underlying deallocator
 * object.
 *
 * <b>Preconditions:</b><ul>
 * <li> <tt>p.get() != NULL</tt> (throws <tt>NullReferenceError</tt>)
 * <li> The deallocator object type used to construct <tt>p</tt> is same as <tt>Dealloc_T</tt>
 *      (throws <tt>NullReferenceError</tt>)
 * </ul>
 *
 * \relates RCP
 */
template<class Dealloc_T, class T>
Dealloc_T& get_nonconst_dealloc( const RCP<T>& p );


/** \brief Return a pointer to the underlying <tt>const</tt> deallocator
 * object if it exists.
 *
 * <b>Preconditions:</b><ul>
 * <li> <tt>p.get() != NULL</tt> (throws <tt>NullReferenceError</tt>)
 * </ul>
 *
 * <b>Postconditions:</b><ul>
 * <li> If the deallocator object type used to construct <tt>p</tt> is same as <tt>Dealloc_T</tt>
 *      then <tt>return!=NULL</tt>, otherwise <tt>return==NULL</tt>
 * </ul>
 *
 * \relates RCP
 */
template<class Dealloc_T, class T>
Ptr<const Dealloc_T> get_optional_dealloc( const RCP<T>& p );


/** \brief Return a pointer to the underlying non-<tt>const</tt> deallocator
 * object if it exists.
 *
 * <b>Preconditions:</b><ul>
 * <li> <tt>p.get() != NULL</tt> (throws <tt>NullReferenceError</tt>)
 * </ul>
 *
 * <b>Postconditions:</b><ul>
 * <li> If the deallocator object type used to construct <tt>p</tt> is same as <tt>Dealloc_T</tt>
 *      then <tt>return!=NULL</tt>, otherwise <tt>return==NULL</tt>
 * </ul>
 *
 * \relates RCP
 */
template<class Dealloc_T, class T>
Ptr<Dealloc_T> get_optional_nonconst_dealloc( const RCP<T>& p );


/** \brief Get a const reference to an embedded object that was set by calling
 * <tt>rcpWithEmbeddedObjPreDestroy()</tt>,
 * <tt>rcpWithEmbeddedObjPostDestory()</tt>, or <tt>rcpWithEmbeddedObj()</tt>.
 *
 * \relates RCP
 */
template<class TOrig, class Embedded, class T>
const Embedded& getEmbeddedObj( const RCP<T>& p );


/** \brief Get a non-const reference to an embedded object that was set by
 * calling <tt>rcpWithEmbeddedObjPreDestroy()</tt>,
 * <tt>rcpWithEmbeddedObjPostDestory()</tt>, or <tt>rcpWithEmbeddedObj()</tt>.
 *
 * \relates RCP
 */
template<class TOrig, class Embedded, class T>
Embedded& getNonconstEmbeddedObj( const RCP<T>& p );


/** \brief Get an optional Ptr to a const embedded object if it was set by
 * calling <tt>rcpWithEmbeddedObjPreDestroy()</tt>,
 * <tt>rcpWithEmbeddedObjPostDestory()</tt>, or <tt>rcpWithEmbeddedObj()</tt>.
 *
 * \relates RCP
 */
template<class TOrig, class Embedded, class T>
Ptr<const Embedded> getOptionalEmbeddedObj( const RCP<T>& p );


/** \brief Get an optional Ptr to a non-const embedded object if it was set by
 * calling <tt>rcpWithEmbeddedObjPreDestroy()</tt>,
 * <tt>rcpWithEmbeddedObjPostDestory()</tt>, or <tt>rcpWithEmbeddedObj()</tt>.
 *
 * \relates RCP
 */
template<class TOrig, class Embedded, class T>
Ptr<Embedded> getOptionalNonconstEmbeddedObj( const RCP<T>& p );


/** \brief Get the parent back from an inverted ownership RCP.
 *
 * Retrieves the RCP<ParentT> object set through
 * <tt>rcpWithInvertedObjOwnership()</tt>.
 */
template<class ParentT, class T>
RCP<ParentT> getInvertedObjOwnershipParent(const RCP<T> &invertedChild);


/** \brief Output stream inserter.
 *
 * The implementation of this function just print pointer addresses and
 * therefore puts no restrictions on the data types involved.
 *
 * \relates RCP
 */
template<class T>
std::ostream& operator<<( std::ostream& out, const RCP<T>& p );


} // end namespace Teuchos


#endif  // TEUCHOS_RCP_DECL_HPP