|
Teuchos Package Browser (Single Doxygen Collection)
Version of the Day
|
Go to the documentation of this file.
42 #ifndef TEUCHOS_RCP_NODE_HPP
43 #define TEUCHOS_RCP_NODE_HPP
62 #if defined(HAVE_TEUCHOSCORE_CXX11) && defined(HAVE_TEUCHOS_THREAD_SAFE) && !defined(DISABLE_ATOMIC_COUNTERS)
70 # define TEUCHOS_RCP_DECL_ATOMIC(VAR, T) std::atomic<T> VAR
72 # define TEUCHOS_RCP_DECL_ATOMIC(VAR, T) T VAR
104 true, std::logic_error,
"Teuchos::RCPNode: ERCPStrength enum value "
105 << strength <<
" is invalid (neither RCP_STRONG = " <<
RCP_STRONG
106 <<
" nor RCP_WEAK = " <<
RCP_WEAK <<
").");
110 #endif // TEUCHOS_DEBUG
158 : has_ownership_(has_ownership_in), extra_data_map_(NULL)
160 ,insertion_number_(-1)
170 delete extra_data_map_;
179 int strong_count_non_atomic = count_[
RCP_STRONG];
181 if (strong_count_non_atomic == 0) {
184 if (std::atomic_compare_exchange_weak( &count_[
RCP_STRONG],
185 &strong_count_non_atomic, strong_count_non_atomic + 1)) {
216 if (++count_[strength] == 1) {
226 #ifdef BREAK_THREAD_SAFETY_OF_DEINCR_COUNT
228 return count_[strength];
230 return --count_[strength];
236 has_ownership_ = has_ownership_in;
241 return has_ownership_;
245 const any &extra_data,
const std::string& name,
248 any& get_extra_data(
const std::string& type_name,
249 const std::string& name );
252 const std::string& name
255 return const_cast<RCPNode*>(
this)->get_extra_data(type_name, name);
258 any* get_optional_extra_data(
const std::string& type_name,
259 const std::string& name );
262 const std::string& type_name,
const std::string& name
265 return const_cast<RCPNode*>(
this)->get_optional_extra_data(type_name, name);
268 virtual bool is_valid_ptr()
const = 0;
270 virtual void delete_obj() = 0;
272 virtual void throw_invalid_obj_exception(
273 const std::string& rcp_type_name,
276 const void* rcp_obj_ptr
279 virtual const std::string get_base_obj_type_name()
const = 0;
282 virtual const void* get_base_obj_map_key_void_ptr()
const = 0;
289 impl_pre_delete_extra_data();
295 : extra_data(_extra_data), destroy_when(_destroy_when)
310 void impl_pre_delete_extra_data();
317 int insertion_number_;
319 void set_insertion_number(
int insertion_number_in)
321 insertion_number_ = insertion_number_in;
323 int insertion_number()
const
325 return insertion_number_;
327 #endif // TEUCHOS_DEBUG
347 #define TEUCHOS_CATCH_AND_ABORT \
348 catch(const std::exception &excpt) { abort_for_exception_in_destructor(excpt); } \
349 catch(const int &excpt_code) { abort_for_exception_in_destructor(excpt_code); } \
350 catch(...) { abort_for_exception_in_destructor(); }
378 : maxNumRCPNodes(0), totalNumRCPNodeAllocations(0),
379 totalNumRCPNodeDeletions(0)
396 static bool isTracingActiveRCPNodes();
398 #if defined(TEUCHOS_DEBUG) && !defined(HAVE_TEUCHOS_DEBUG_RCP_NODE_TRACING)
416 static void setTracingActiveRCPNodes(
bool tracingActiveNodes);
422 static int numActiveRCPNodes();
428 static void printRCPNodeStatistics(
434 static void setPrintRCPNodeStatisticsOnExit(
435 bool printRCPNodeStatisticsOnExit);
440 static bool getPrintRCPNodeStatisticsOnExit();
445 static void setPrintActiveRcpNodesOnExit(
bool printActiveRcpNodesOnExit);
450 static bool getPrintActiveRcpNodesOnExit();
467 static void printActiveRCPNodes(std::ostream &out);
480 static void addNewRCPNode(
RCPNode* rcp_node,
481 const std::string &info );
488 static void removeRCPNode(
RCPNode* rcp_node );
501 #ifdef HAS_TEUCHOS_GET_BASE_OBJ_VOID_PTR
502 return getBaseObjVoidPtr(p);
509 return static_cast<const void*>(p);
519 static RCPNode* getExistingRCPNodeGivenLookupKey(
520 const void* lookupKey);
531 return getExistingRCPNodeGivenLookupKey(getRCPNodeBaseObjMapKeyVoidPtr(p));
535 static std::string getActiveRCPNodeHeaderString();
538 static std::string getCommonDebugNotesString();
546 # define TEUCHOS_RCP_INSERION_NUMBER_STR() \
547 " insertionNumber: " << rcp_node_ptr->insertion_number() << "\n"
549 # define TEUCHOS_RCP_INSERION_NUMBER_STR()
558 template<
class T,
class Dealloc_T>
565 base_obj_map_key_void_ptr_(
RCPNodeTracer::getRCPNodeBaseObjMapKeyVoidPtr(p)),
571 RCPNodeTmpl(T* p, Dealloc_T dealloc,
bool has_ownership_in, ENull)
574 base_obj_map_key_void_ptr_(0),
590 "Error, the underlying object must be explicitly deleted before deleting"
591 " the node object!" );
608 deleted_ptr_ = tmp_ptr;
618 TEUCHOS_CATCH_AND_ABORT
625 const std::string& rcp_type_name,
628 const void* rcp_obj_ptr
632 const T* deleted_ptr =
641 "Error, an attempt has been made to dereference the underlying object\n"
642 "from a weak smart pointer object where the underling object has already\n"
643 "been deleted since the strong count has already gone to zero.\n"
645 "Context information:\n"
647 " RCP type: " << rcp_type_name <<
"\n"
648 " RCP address: " << rcp_ptr <<
"\n"
649 " RCPNode type: " <<
typeName(*
this) <<
"\n"
650 " RCPNode address: " << rcp_node_ptr <<
"\n"
652 " RCP ptr address: " << rcp_obj_ptr <<
"\n"
653 " Concrete ptr address: " << deleted_ptr <<
"\n"
672 return "UnknownType";
677 const void* get_base_obj_map_key_void_ptr()
const
679 return base_obj_map_key_void_ptr_;
685 const void *base_obj_map_key_void_ptr_;
762 : node_ (node), strength_ (strength_in)
766 #endif // TEUCHOS_DEBUG
775 std::ostringstream os;
776 os <<
"{T=Unknown, ConcreteT=Unknown, p=Unknown,"
777 <<
" has_ownership="<<node_->has_ownership()<<
"}";
782 #endif // TEUCHOS_DEBUG
789 const std::string &ConcreteT_name,
790 const bool has_ownership_in,
792 : node_ (node), strength_ (strength_in)
798 std::ostringstream os;
799 os <<
"{T="<<T_name<<
", ConcreteT="<< ConcreteT_name
800 <<
", p="<<static_cast<const void*>(p)
801 <<
", has_ownership="<<has_ownership_in<<
"}";
805 #endif // TEUCHOS_DEBUG
809 : node_ (node_ref.node_), strength_ (node_ref.strength_)
816 std::swap (node_ref.
node_, node_);
817 std::swap (node_ref.
strength_, strength_);
832 node_ = node_ref.
node_;
850 return possibleStrongNode;
882 return node_->is_valid_ptr();
889 return node_ == node2.
node_;
894 return node_->strong_count();
901 return node_->weak_count();
908 return node_->strong_count() + node_->weak_count();
915 return node_->strong_count();
927 node_->has_ownership(has_ownership_in);
933 return node_->has_ownership();
938 const any &extra_data,
const std::string& name,
942 debug_assert_not_null();
943 node_->set_extra_data(extra_data, name, destroy_when, force_unique);
947 const std::string& name
950 debug_assert_not_null();
951 return node_->get_extra_data(type_name, name);
955 const std::string& name
958 return const_cast<RCPNodeHandle*>(
this)->get_extra_data(type_name, name);
962 const std::string& type_name,
const std::string& name
965 debug_assert_not_null();
966 return node_->get_optional_extra_data(type_name, name);
970 const std::string& type_name,
const std::string& name
973 return const_cast<RCPNodeHandle*>(
this)->get_optional_extra_data(type_name, name);
980 throw_null_ptr_error(
typeName(*
this));
984 template<
class RCPType>
989 if (!is_valid_ptr()) {
990 node_->throw_invalid_obj_exception(
typeName(rcp_obj),
991 this, node_, rcp_obj.access_private_ptr() );
995 template<
class RCPType>
999 assert_valid_ptr(rcp_obj);
1002 #ifdef TEUCHOS_DEBUG
1003 const void* get_base_obj_map_key_void_ptr()
const
1006 return node_->get_base_obj_map_key_void_ptr();
1050 void unbindOneStrong();
1051 void unbindOneTotal();
1099 node_->has_ownership(
false);
1100 node_->delete_obj();
1127 #if defined(TEUCHOS_DEBUG) && !defined(HAVE_TEUCHOS_DEBUG_RCP_NODE_TRACING)
1129 class SetTracingActiveNodesStack {
1131 SetTracingActiveNodesStack()
1132 {RCPNodeTracer::setTracingActiveRCPNodes(
true);}
1133 ~SetTracingActiveNodesStack()
1134 {RCPNodeTracer::setTracingActiveRCPNodes(
false);}
1137 # define SET_RCPNODE_TRACING() Teuchos::SetTracingActiveNodesStack setTracingActiveNodesStack;
1141 # define SET_RCPNODE_TRACING() (void)0
1143 #endif // defined(TEUCHOS_DEBUG) && !defined(HAVE_TEUCHOS_DEBUG_RCP_NODE_TRACING)
1149 #endif // TEUCHOS_RCP_NODE_HPP
static std::string name()
void has_ownership(bool has_ownership_in)
int count() const
The strong count; retained for backwards compatibility.
void debug_assert_not_null() const
extra_data_map_t * extra_data_map_
Dangling reference error exception class.
#define TEUCHOS_RCP_DECL_ATOMIC(VAR, T)
RCPNodeHandle(const RCPNodeHandle &node_ref)
Copy constructor.
const any & get_extra_data(const std::string &type_name, const std::string &name) const
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
This macro is designed to be a short version of TEUCHOS_TEST_FOR_EXCEPTION() that is easier to call.
RCPNode(bool has_ownership_in)
Sets up node tracing and prints remaining RCPNodes on destruction.
std::ostream & operator<<(std::ostream &out, const RCPNodeHandle &node)
Ouput stream operator for RCPNodeHandle.
bool attemptConvertWeakToStrong()
long int totalNumRCPNodeAllocations
RCPNodeHandle(ENull null_arg=null)
Default constructor.
bool has_ownership() const
virtual bool is_valid_ptr() const
Debug-mode RCPNode tracing class.
ERCPNodeLookup
Used to determine if RCPNode lookup is performed or not.
static std::string getCommonDebugNotesString()
Common error message string on how to debug RCPNode problems.
RCPNodeHandle create_strong() const
Return a strong handle.
RCPNode * node_ptr() const
Return a pointer to the underlying RCPNode.
static bool isTracingActiveRCPNodes()
Return if we are tracing active nodes or not.
#define TEUCHOS_ASSERT(assertion_test)
This macro is throws when an assert fails.
void debug_assert_valid_ptr(const RCPType &rcp_obj) const
const any & get_extra_data(const std::string &type_name, const std::string &name) const
Teuchos::map< std::string, extra_data_entry_t > extra_data_map_t
#define TEUCHOSCORE_LIB_DLL_EXPORT
any & get_extra_data(const std::string &type_name, const std::string &name)
const Dealloc_T & get_dealloc() const
#define TEUCHOS_TEST_FOR_TERMINATION(terminate_test, msg)
This macro is to be used instead of TEUCHOS_TEST_FOR_EXCEPTION() to report an error in situations whe...
const any * get_optional_extra_data(const std::string &type_name, const std::string &name) const
const std::string get_base_obj_type_name() const
RCPNodeThrowDeleter(RCPNode *node)
int weak_count() const
The weak count for this RCPNode, or 0 if the node is NULL.
const any * get_optional_extra_data(const std::string &type_name, const std::string &name) const
RCPNodeTmpl(T *p, Dealloc_T dealloc, bool has_ownership_in)
For defined types.
RCPNodeHandle(RCPNode *node, ERCPStrength strength_in=RCP_STRONG, bool newNode=true)
Constructor that takes a pointer to an RCPNode.
RCPNodeHandle create_strong_lock() const
Return a strong handle if possible using thread safe atomics.
void release()
Releaes the RCPNode pointer before the destructor is called.
virtual void throw_invalid_obj_exception(const std::string &rcp_type_name, const void *rcp_ptr, const RCPNode *rcp_node_ptr, const void *rcp_obj_ptr) const
~RCPNodeThrowDeleter()
Called with node_!=0 when an exception is thrown.
bool same_node(const RCPNodeHandle &node2) const
Whether the RCPNode for which node2 is a handle is the same RCPNode as this object's RCPNode.
void debugAssertStrength(ERCPStrength strength)
~RCPNodeHandle()
Destructor.
Defines basic traits returning the name of a type in a portable and readable way.
Teuchos header file which uses auto-configuration information to include necessary C++ headers.
Node class to keep track of address and the reference count for a reference-counted utility class and...
bool has_ownership() const
bool is_valid_ptr() const
Whether the underlying pointer is valid.
void swap(RCPNodeHandle &node_ref)
Swap the contents of node_ref with *this.
static std::string toString(const ERCPStrength &t)
int deincr_count(const ERCPStrength strength)
bool is_node_null() const
Whether the underlying RCPNode is NULL.
long int totalNumRCPNodeDeletions
Deletes a (non-owning) RCPNode but not it's underlying object in case of a throw.
void incr_count(const ERCPStrength strength)
int total_count() const
The sum of the weak and string counts.
Default traits class for converting objects into strings.
virtual void delete_obj()
Delete the underlying object. Will abort if an exception is detected in the destructor.
Dealloc_T & get_nonconst_dealloc()
Handle class that manages the RCPNode's reference counting.
RCPNodeTmpl & operator=(const RCPNodeTmpl &)
Provides std::map class for deficient platforms.
EPrePostDestruction
Used to specify a pre or post destruction of extra data.
Modified boost::any class for holding a templated value.
void pre_delete_extra_data()
void set_extra_data(const any &extra_data, const std::string &name, EPrePostDestruction destroy_when, bool force_unique)
ERCPStrength strength() const
The strength of this handle.
static void addNewRCPNode(RCPNode *rcp_node, const std::string &info)
Add new RCPNode to the global list.
ERCPStrength
Used to specify if the pointer is weak or strong.
#define TEUCHOS_RCP_INSERION_NUMBER_STR()
RCPNodeTmpl(T *p, Dealloc_T dealloc, bool has_ownership_in, ENull)
For undefined types .
void has_ownership(bool has_ownership_in)
static RCPNode * getExistingRCPNode(T *p)
Return a raw pointer to an existing owning RCPNode given the address to the underlying object if it e...
RCPNodeHandle create_weak() const
Return a weak handle.
std::string typeName(const T &t)
Template function for returning the concrete type name of a passed-in object.
void assert_valid_ptr(const RCPType &rcp_obj) const
bool attemptIncrementStrongCountFromNonZeroValue()
attemptIncrementStrongCountFromNonZeroValue() supports weak to strong conversion but this is forward ...
#define TEUCHOS_TEST_FOR_EXCEPT_MSG(throw_exception_test, msg)
This macro is designed to be a short version of TEUCHOS_TEST_FOR_EXCEPTION() that is easier to call.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
int strong_count() const
The strong count for this RCPNode, or 0 if the node is NULL.
Modified boost::any class, which is a container for a templated value.
Templated implementation class of RCPNode that has the responsibility for deleting the reference-coun...
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...
any * get_optional_extra_data(const std::string &type_name, const std::string &name)