Jump to content

  • Log In with Google      Sign In   
  • Create Account


#ActualRyan_001

Posted 19 October 2012 - 09:28 AM

I've been working on a hash container that is sort of a cross between unordered_set and a vector. Its uses open addressing/closed hashing and stores values in continuous memory, expanding like a vector as the load factor gets too high. In order to learn/become a better programmer I've tried to write this container as if it was an stl container, with all the bells, whistles and restrictions. I've been having a problem when it comes to exception safety. In order to support const types in the container, I need to write my own swap/move/copy functions in terms of copy construct and destruct. So to swap two pointers I came up with this:

UVTEMPLATE void UVBASE::swap_values (pointer p0, pointer p1) {

   value_type t(move(*p0));

   allocator.destroy(p0);
   try { allocator.construct(p0,move(*p1)); }
   catch (...) { allocator.construct(p0,sentinel()); throw; }

   allocator.destroy(p1);
   try { allocator.construct(p1,move(t)); }
   catch (...) { allocator.construct(p1,sentinel()); throw; }
   }

I think that should work (though TBH I haven't had the chance to compile/test it) but the judicious use of try/catch blocks has me worried about performance. How do normal stl containers handle this? For example:

vector<const int> v;
v.push_back(2);
v.push_back(8);
v.insert(v.begin(),10);
cout << "v[0] = " << v[0] << endl;

works fine, compiles and runs as expected. How do they handle the situation where a copy constructor throws an exception when moving/copying/swapping items around?

#1Ryan_001

Posted 19 October 2012 - 09:20 AM

I've been working on a hash container that is sort of a cross between unordered_set and a vector. Its uses open addressing/closed hashing and stores values in continuous memory, expanding like a vector as the load factor gets too high. In order to learn/become a better programmer I've tried to write this container as if it was an stl container, with all the bells, whistles and restrictions. I've been having a problem when it comes to exception safety. In order to support const types in the container, I need to write my own swap/move/copy functions in terms of copy construct and destruct. So to swap two pointers I came up with this:

UVTEMPLATE void UVBASE::swap_values (pointer p0, pointer p1) {

   value_type t(std::move(*p0));

   allocator.destroy(p0);
   try { allocator.construct(p0,std::move(*p1)); }
   catch (...) { allocator.construct(p0,sentinel()); throw; }

   allocator.destroy(p1);
   try { allocator.construct(p1,std::move(t)); }
   catch (...) { allocator.construct(p1,sentinel()); throw; }
   }

I think that should work (though TBH I haven't had the chance to compile/test it) but the judicious use of try/catch blocks has me worried about performance. How do normal stl containers handle this? For example:

std::vector<const int> v;
v.push_back(2);
v.push_back(8);
v.insert(v.begin(),10);
cout << "v[0] = " << v[0] << endl;

works fine, compiles and runs as expected. How do they handle the situation where a copy constructor throws an exception when moving/copying/swapping items around?

PARTNERS