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 >::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
00139 
00140 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines