|
Sierra Toolkit
Version of the Day
|
00001 /*------------------------------------------------------------------------*/ 00002 /* Copyright 2010 Sandia Corporation. */ 00003 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */ 00004 /* license for use of this work by or on behalf of the U.S. Government. */ 00005 /* Export of this program may require a license from the */ 00006 /* United States Government. */ 00007 /*------------------------------------------------------------------------*/ 00008 00009 #include <algorithm> 00010 #include <stdexcept> 00011 #include <iostream> 00012 #include <sstream> 00013 #include <assert.h> 00014 00015 #include <stk_util/util/CSet.hpp> 00016 00017 namespace stk_classic { 00018 00019 namespace { 00020 00021 typedef void (* DeleteFunction )( void * ); 00022 00023 typedef std::pair< const std::type_info * , DeleteFunction > Manager ; 00024 00025 // Comparison for sorted vector 00026 00027 struct less_cset { 00028 bool operator()( const Manager & lhs , 00029 const std::type_info & rhs ) const ; 00030 bool operator()( const std::type_info & lhs , 00031 const Manager & rhs ) const ; 00032 }; 00033 00034 // On some systems, namely AIX, std::type_info::before(...) 00035 // has a bug where it returns true instead of false for equality. 00036 // Thus we pay a small price on all systems to specifically 00037 // test for and eliminate equality. 00038 00039 bool less_cset::operator()( const Manager & lhs , 00040 const std::type_info & rhs ) const 00041 { return lhs.first->before( rhs ) && * lhs.first != rhs ; } 00042 00043 bool less_cset::operator()( const std::type_info & lhs , 00044 const Manager & rhs ) const 00045 { return lhs.before( *rhs.first ) && lhs != *rhs.first ; } 00046 00047 00048 std::vector< Manager >::iterator 00049 lower_bound( std::vector< Manager > & v , const std::type_info & t ) 00050 { 00051 std::vector< Manager >::iterator i = v.begin(); 00052 std::vector< Manager >::iterator j = v.end(); 00053 00054 return std::lower_bound( i , j , t , less_cset() ); 00055 } 00056 00057 } 00058 00059 struct equal_cset { 00060 bool operator()(const Manager& lhs, const std::type_info& rhs) const 00061 { return *lhs.first == rhs; } 00062 bool operator()(const std::type_info& lhs, const Manager& rhs) const 00063 { return lhs == *rhs.first; } 00064 }; 00065 00066 //---------------------------------------------------------------------- 00067 00068 const void * CSet::p_get( const std::type_info & t ) const 00069 { 00070 for(std::vector<Manager>::const_iterator it=m_manager.begin(), end=m_manager.end(); it!=end; ++it) { 00071 if (*it->first == t) return m_value[it-m_manager.begin()]; 00072 } 00073 00074 return NULL ; 00075 } 00076 00077 const void * 00078 CSet::p_insert( const Manager & m , const void * v ) 00079 { 00080 std::vector< Manager >::iterator im = lower_bound( m_manager , * m.first ); 00081 00082 const size_t offset = im - m_manager.begin(); 00083 00084 assert(m_value.size() == m_manager.size()); 00085 std::vector<const void *>::iterator iv = m_value.begin(); 00086 std::advance( iv , offset ); 00087 00088 if ( im == m_manager.end() || * m.first != * im->first ) { 00089 im = m_manager.insert( im , m ); 00090 iv = m_value .insert( iv , v ); 00091 } 00092 00093 assert(iv != m_value.end()); 00094 return *iv ; 00095 } 00096 00097 bool CSet::p_remove( const std::type_info & t , const void * v ) 00098 { 00099 bool result = false; 00100 const std::vector< Manager >::iterator im = lower_bound( m_manager , t ); 00101 00102 if (im != m_manager.end()) { 00103 const size_t offset = im - m_manager.begin(); 00104 00105 if (offset <= m_value.size()) { 00106 std::vector<const void *>::iterator iv = m_value.begin(); 00107 std::advance( iv , offset ); 00108 00109 result = t == * im->first && v == * iv ; 00110 00111 if ( result ) { 00112 m_manager.erase( im ); 00113 m_value .erase( iv ); 00114 } 00115 } 00116 } 00117 return result ; 00118 } 00119 00120 //---------------------------------------------------------------------- 00121 00122 CSet::~CSet() 00123 { 00124 try { 00125 const size_t n = m_manager.size(); 00126 for ( size_t i = 0 ; i < n ; ++i ) { 00127 try { 00128 if ( m_manager[i].second ) { 00129 (*m_manager[i].second)( const_cast<void*>( m_value[i] ) ); 00130 } 00131 } catch(...) {} 00132 } 00133 } catch(...) {} 00134 } 00135 00136 CSet::CSet() : m_manager(), m_value() {} 00137 00138 } // namespace stk_classic 00139 00140