Sierra Toolkit Version of the Day
CSet.cpp
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 {
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 >::const_iterator
00049 lower_bound( const std::vector< Manager > & v , const std::type_info & t )
00050 {
00051   std::vector< Manager >::const_iterator i = v.begin();
00052   std::vector< Manager >::const_iterator j = v.end();
00053 
00054   return std::lower_bound( i , j , t , less_cset() );
00055 }
00056 
00057 std::vector< Manager >::iterator
00058 lower_bound( std::vector< Manager > & v , const std::type_info & t )
00059 {
00060   std::vector< Manager >::iterator i = v.begin();
00061   std::vector< Manager >::iterator j = v.end();
00062 
00063   return std::lower_bound( i , j , t , less_cset() );
00064 }
00065 
00066 }
00067 
00068 //----------------------------------------------------------------------
00069 
00070 const void * CSet::p_get( const std::type_info & t ) const
00071 {
00072   const void * result = NULL ;
00073 
00074   const std::vector< Manager >::const_iterator im = lower_bound(m_manager,t);
00075 
00076   if ( im < m_manager.end() && t == * im->first ) {
00077     const size_t offset = im - m_manager.begin();
00078     result = m_value[ offset ];
00079   }
00080 
00081   return result ;
00082 }
00083 
00084 const void *
00085 CSet::p_insert( const Manager & m , const void * v )
00086 {
00087   std::vector< Manager >::iterator im = lower_bound( m_manager , * m.first );
00088 
00089   const size_t offset = im - m_manager.begin();
00090 
00091   assert(m_value.size() == m_manager.size());
00092   std::vector<const void *>::iterator iv = m_value.begin();
00093   std::advance( iv , offset );
00094 
00095   if ( im == m_manager.end() || * m.first != * im->first ) {
00096     im = m_manager.insert( im , m );
00097     iv = m_value  .insert( iv , v );
00098   }
00099 
00100   assert(iv != m_value.end());
00101   return *iv ;
00102 }
00103 
00104 bool CSet::p_remove( const std::type_info & t , const void * v )
00105 {
00106   bool result = false;
00107   const std::vector< Manager >::iterator im = lower_bound( m_manager , t );
00108 
00109   if (im != m_manager.end()) {
00110     const size_t offset = im - m_manager.begin();
00111 
00112     if (offset <= m_value.size()) {
00113       std::vector<const void *>::iterator iv = m_value.begin();
00114       std::advance( iv , offset );
00115 
00116       result = t == * im->first && v == * iv ;
00117 
00118       if ( result ) {
00119   m_manager.erase( im );
00120   m_value  .erase( iv );
00121       }
00122     }
00123   }
00124   return result ;
00125 }
00126 
00127 //----------------------------------------------------------------------
00128 
00129 CSet::~CSet()
00130 {
00131   try {
00132     const size_t n = m_manager.size();
00133     for ( size_t i = 0 ; i < n ; ++i ) {
00134       try {
00135         if ( m_manager[i].second ) {
00136           (*m_manager[i].second)( const_cast<void*>( m_value[i] ) );
00137         }
00138       } catch(...) {}
00139     }
00140   } catch(...) {}
00141 }
00142 
00143 CSet::CSet() : m_manager(), m_value() {}
00144 
00145 } // namespace stk
00146 
00147 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends