Sierra Toolkit  Version of the Day
CSet.cpp
1 /*------------------------------------------------------------------------*/
2 /* Copyright 2010 Sandia Corporation. */
3 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */
4 /* license for use of this work by or on behalf of the U.S. Government. */
5 /* Export of this program may require a license from the */
6 /* United States Government. */
7 /*------------------------------------------------------------------------*/
8 
9 #include <algorithm>
10 #include <stdexcept>
11 #include <iostream>
12 #include <sstream>
13 #include <assert.h>
14 
15 #include <stk_util/util/CSet.hpp>
16 
17 namespace stk_classic {
18 
19 namespace {
20 
21 typedef void (* DeleteFunction )( void * );
22 
23 typedef std::pair< const std::type_info * , DeleteFunction > Manager ;
24 
25 // Comparison for sorted vector
26 
27 struct less_cset {
28  bool operator()( const Manager & lhs ,
29  const std::type_info & rhs ) const ;
30  bool operator()( const std::type_info & lhs ,
31  const Manager & rhs ) const ;
32 };
33 
34 // On some systems, namely AIX, std::type_info::before(...)
35 // has a bug where it returns true instead of false for equality.
36 // Thus we pay a small price on all systems to specifically
37 // test for and eliminate equality.
38 
39 bool less_cset::operator()( const Manager & lhs ,
40  const std::type_info & rhs ) const
41 { return lhs.first->before( rhs ) && * lhs.first != rhs ; }
42 
43 bool less_cset::operator()( const std::type_info & lhs ,
44  const Manager & rhs ) const
45 { return lhs.before( *rhs.first ) && lhs != *rhs.first ; }
46 
47 
48 std::vector< Manager >::iterator
49 lower_bound( std::vector< Manager > & v , const std::type_info & t )
50 {
51  std::vector< Manager >::iterator i = v.begin();
52  std::vector< Manager >::iterator j = v.end();
53 
54  return std::lower_bound( i , j , t , less_cset() );
55 }
56 
57 }
58 
59 struct equal_cset {
60  bool operator()(const Manager& lhs, const std::type_info& rhs) const
61  { return *lhs.first == rhs; }
62  bool operator()(const std::type_info& lhs, const Manager& rhs) const
63  { return lhs == *rhs.first; }
64 };
65 
66 //----------------------------------------------------------------------
67 
68 const void * CSet::p_get( const std::type_info & t ) const
69 {
70  for(std::vector<Manager>::const_iterator it=m_manager.begin(), end=m_manager.end(); it!=end; ++it) {
71  if (*it->first == t) return m_value[it-m_manager.begin()];
72  }
73 
74  return NULL ;
75 }
76 
77 const void *
78 CSet::p_insert( const Manager & m , const void * v )
79 {
80  std::vector< Manager >::iterator im = lower_bound( m_manager , * m.first );
81 
82  const size_t offset = im - m_manager.begin();
83 
84  assert(m_value.size() == m_manager.size());
85  std::vector<const void *>::iterator iv = m_value.begin();
86  std::advance( iv , offset );
87 
88  if ( im == m_manager.end() || * m.first != * im->first ) {
89  im = m_manager.insert( im , m );
90  iv = m_value .insert( iv , v );
91  }
92 
93  assert(iv != m_value.end());
94  return *iv ;
95 }
96 
97 bool CSet::p_remove( const std::type_info & t , const void * v )
98 {
99  bool result = false;
100  const std::vector< Manager >::iterator im = lower_bound( m_manager , t );
101 
102  if (im != m_manager.end()) {
103  const size_t offset = im - m_manager.begin();
104 
105  if (offset <= m_value.size()) {
106  std::vector<const void *>::iterator iv = m_value.begin();
107  std::advance( iv , offset );
108 
109  result = t == * im->first && v == * iv ;
110 
111  if ( result ) {
112  m_manager.erase( im );
113  m_value .erase( iv );
114  }
115  }
116  }
117  return result ;
118 }
119 
120 //----------------------------------------------------------------------
121 
122 CSet::~CSet()
123 {
124  try {
125  const size_t n = m_manager.size();
126  for ( size_t i = 0 ; i < n ; ++i ) {
127  try {
128  if ( m_manager[i].second ) {
129  (*m_manager[i].second)( const_cast<void*>( m_value[i] ) );
130  }
131  } catch(...) {}
132  }
133  } catch(...) {}
134 }
135 
136 CSet::CSet() : m_manager(), m_value() {}
137 
138 } // namespace stk_classic
139 
140 
Sierra Toolkit.