Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

No objects should be constructed if they are not inserted

- previously, empty hash table would in fact contain N copies of default
  constructed value_type
  • Loading branch information...
commit 42c5ce7caddf0ec867ee383d83f258e3b0981a8f 1 parent 272acde
@pmachata authored
Showing with 38 additions and 6 deletions.
  1. +12 −0 hash.cc
  2. +26 −6 hash.hh
View
12 hash.cc
@@ -242,6 +242,14 @@ testsuite ()
std::cout << std::endl;
}
+struct D
+{
+ D ()
+ {
+ assert (!"This ctor should never be called!");
+ }
+};
+
int
main (int argc, char *argv[])
{
@@ -259,6 +267,10 @@ main (int argc, char *argv[])
tests<hashtab<int, int, 3>, 2> ();
tests<hashtab<std::string, std::string, 3>, 2> ();
+ {
+ hashtab<int, D, 3> _;
+ }
+
std::cout << std::endl;
testsuite<5> ();
testsuite<17> ();
View
32 hash.hh
@@ -86,7 +86,11 @@ struct hashtab
private:
- std::array<value_type, N> _table;
+ struct slot
+ {
+ unsigned char bytes[sizeof (value_type)]; // payload
+ };
+ slot _table[N];
std::bitset<N> _taken;
size_type _size;
@@ -101,7 +105,7 @@ private:
size_type d = _hash2 (pos);
found = false;
for (; _taken[pos]; pos = (pos + d) % N)
- if (_eq (_table[pos].first, e))
+ if (_eq (tab (pos).first, e))
{
found = true;
break;
@@ -229,7 +233,7 @@ public:
value_type &
operator * ()
{
- return this->_parent->_table[this->_pos];
+ return this->_parent->tab (this->_pos);
}
value_type *
@@ -265,7 +269,7 @@ public:
value_type const &
operator * ()
{
- return this->_parent->_table[this->_pos];
+ return this->_parent->tab (this->_pos);
}
value_type const *
@@ -299,6 +303,22 @@ public:
}
private:
+ value_type const &
+ tab (size_type i) const
+ {
+ unsigned char const *bytes = _table[i].bytes;
+ value_type const &object = *reinterpret_cast<const_pointer> (bytes);
+ return object;
+ }
+
+ value_type &
+ tab (size_type i)
+ {
+ unsigned char *bytes = _table[i].bytes;
+ value_type &object = *reinterpret_cast<pointer> (bytes);
+ return object;
+ }
+
// We have to ignore what's in the unused (and uninitialized)
// portions of the table.
bool
@@ -306,7 +326,7 @@ private:
{
// N.B. at this point we already know that _taken == other._taken
for (size_type i = 0; i < N; ++i)
- if (_taken[i] && _table[i] != other._table[i])
+ if (_taken[i] && tab (i) != other.tab (i))
return false;
return true;
}
@@ -378,7 +398,7 @@ public:
return std::make_pair (iterator (this, it._pos), false);
_taken[it._pos] = true;
- _table[it._pos] = emt;
+ new (&_table[it._pos]) value_type (emt);
++_size;
return std::make_pair (iterator (this, it._pos), true);
Please sign in to comment.
Something went wrong with that request. Please try again.