Teuchos_RefCountPtr.cpp

00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 //                    Teuchos: Common Tools Package
00005 //                 Copyright (2004) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00025 // 
00026 // ***********************************************************************
00027 // @HEADER
00028 
00029 #include "Teuchos_RefCountPtr.hpp"
00030 #include "Teuchos_TestForException.hpp"
00031 #include "Teuchos_VerboseObject.hpp"
00032 
00033 namespace Teuchos {
00034 
00035 void PrivateUtilityPack::throw_null( const std::string &type_name )
00036 {
00037   TEST_FOR_EXCEPTION(
00038     true, std::logic_error
00039     ,"RefCountPtr<"<<type_name<<">::assert_not_null() : You can not"
00040     " call operator->() or operator*() if get()==NULL!" );
00041 }
00042 
00043 namespace PrivateUtilityPack {
00044 
00045 void RefCountPtr_node::set_extra_data( const any &extra_data, const std::string& name, EPrePostDestruction destroy_when, bool force_unique )
00046 {
00047   if(extra_data_map_==NULL) {
00048     extra_data_map_ = new extra_data_map_t;
00049   }
00050   const std::string type_and_name( extra_data.type().name() + std::string(":") + name );
00051   if( !extra_data_map_->empty() && force_unique ) {
00052     extra_data_map_t::iterator itr = extra_data_map_->find(type_and_name);
00053     TEST_FOR_EXCEPTION(
00054       itr != extra_data_map_->end(), std::invalid_argument
00055       ,"Error, the type:name pair \'" << type_and_name << "\' already exists and force_unique==true!" );
00056   }
00057   (*extra_data_map_)[type_and_name] = extra_data_entry_t(extra_data,destroy_when); // This may add or replace!
00058 }
00059 
00060 any& RefCountPtr_node::get_extra_data( const std::string& type_name, const std::string& name )
00061 {
00062   TEST_FOR_EXCEPTION(
00063     extra_data_map_==NULL, std::invalid_argument
00064     ,"Error, no extra data has been set yet!" );
00065   any *extra_data = get_optional_extra_data(type_name,name);
00066   if(extra_data) return *extra_data;
00067   const std::string type_and_name( type_name + std::string(":") + name );
00068   TEST_FOR_EXCEPTION(
00069     extra_data == NULL, std::invalid_argument
00070     ,"Error, the type:name pair \'" << type_and_name << "\' is not found!" );
00071   return *extra_data; // Will never be executed!
00072 }
00073 
00074 any* RefCountPtr_node::get_optional_extra_data( const std::string& type_name, const std::string& name )
00075 {
00076   if( extra_data_map_ == NULL ) return NULL;
00077   const std::string type_and_name( type_name + std::string(":") + name );
00078   extra_data_map_t::iterator itr = extra_data_map_->find(type_and_name);
00079   if(itr != extra_data_map_->end())
00080     return &(*itr).second.extra_data;
00081   return NULL;
00082 }
00083 
00084 void RefCountPtr_node::impl_pre_delete_extra_data()
00085 {
00086   for( extra_data_map_t::iterator itr = extra_data_map_->begin(); itr != extra_data_map_->end(); ++itr ) {
00087     extra_data_map_t::value_type &entry = *itr;
00088     if(entry.second.destroy_when == PRE_DESTROY)
00089       entry.second.extra_data = any();
00090   }
00091 }
00092 
00093 } // namespace PrivateUtilityPack
00094 
00095 typedef std::map<PrivateUtilityPack::RefCountPtr_node*,std::string>  rcp_node_list_t;
00096 
00097 rcp_node_list_t rcp_node_list;
00098 
00099 void PrivateUtilityPack::add_new_RefCountPtr_node( RefCountPtr_node* rcp_node, const std::string &info )
00100 {
00101   rcp_node_list[rcp_node] = info;
00102 }
00103 
00104 void PrivateUtilityPack::remove_RefCountPtr_node( RefCountPtr_node* rcp_node )
00105 {
00106   const rcp_node_list_t::iterator itr = rcp_node_list.find(rcp_node);
00107   TEST_FOR_EXCEPT_PRINT(itr==rcp_node_list.end(),&std::cerr);
00108   rcp_node_list.erase(itr);
00109 }
00110 
00111 void PrivateUtilityPack::print_active_RefCountPtr_nodes(std::ostream &out)
00112 {
00113 #ifdef TEUCHOS_SHOW_ACTIVE_REFCOUNTPTR_NODE_TRACE
00114   std::cerr << "\nCalled PrivateUtilityPack::print_active_RefCountPtr_nodes() : rcp_node_list.size() = " << rcp_node_list.size() << "\n";
00115 #endif // TEUCHOS_SHOW_ACTIVE_REFCOUNTPTR_NODE_TRACE
00116   rcp_node_list_t::const_iterator itr = rcp_node_list.begin();
00117   if(itr != rcp_node_list.end()) {
00118     out
00119       << "\n***"
00120       << "\n*** Warning! The following Teucho::RefCountPtr_node objects were created but have"
00121       << "\n*** not been destoryed yet.  This may be an indication that these objects may"
00122       << "\n*** be involved in a circular dependency!  A memory checking tool may complain"
00123       << "\n*** that these objects are not destoryed correctly."
00124       << "\n***\n";
00125     while( itr != rcp_node_list.end() ) {
00126       const rcp_node_list_t::value_type
00127         entry = *itr;
00128       out << "\n  RefCountPtr_node address = \'" << entry.first << "\', information = " << entry.second;
00129       ++itr;
00130     }
00131     out << "\n";
00132   }
00133 }
00134 
00135 namespace PrivateUtilityPack {
00136 
00137 PrintActiveRefCountPtrNodes::PrintActiveRefCountPtrNodes()
00138 {
00139 #ifdef TEUCHOS_SHOW_ACTIVE_REFCOUNTPTR_NODE_TRACE
00140   std::cerr << "\nCalled PrintActiveRefCountPtrNodes::PrintActiveRefCountPtrNodes() : count = " << count_ << "\n";
00141 #endif // TEUCHOS_SHOW_ACTIVE_REFCOUNTPTR_NODE_TRACE
00142   ++count_;
00143 }
00144 
00145 PrintActiveRefCountPtrNodes::~PrintActiveRefCountPtrNodes()
00146 {
00147 #ifdef TEUCHOS_SHOW_ACTIVE_REFCOUNTPTR_NODE_TRACE
00148   std::cerr << "\nCalled PrintActiveRefCountPtrNodes::~PrintActiveRefCountPtrNodes() : count = " << count_ << "\n";
00149 #endif // TEUCHOS_SHOW_ACTIVE_REFCOUNTPTR_NODE_TRACE
00150   if(--count_ == 0 ) {
00151 #ifdef TEUCHOS_SHOW_ACTIVE_REFCOUNTPTR_NODE_TRACE
00152     std::cerr << "\nPrint active nodes!\n";
00153 #endif // TEUCHOS_SHOW_ACTIVE_REFCOUNTPTR_NODE_TRACE
00154     print_active_RefCountPtr_nodes(std::cerr);
00155   }
00156 }
00157 
00158 void PrintActiveRefCountPtrNodes::foo()
00159 {
00160   int dummy = count_;
00161   ++dummy; // Avoid unused variable warning (bug 2664)
00162 }
00163 
00164 int PrintActiveRefCountPtrNodes::count_ = 0;
00165 
00166 } // namespace PrivateUtilityPack
00167 
00168 } // namespace Teuchos

Generated on Thu Sep 18 12:30:30 2008 for Teuchos - Trilinos Tools Package by doxygen 1.3.9.1