diff options
author | Jacques Lucke <jacques@blender.org> | 2020-08-24 18:24:13 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2020-08-24 18:24:13 +0300 |
commit | 8e18a9984505514a229d66b38fff31d930367968 (patch) | |
tree | 97bb3e6f766e997df712bf081e05e027648e2c28 /source/blender/blenlib/BLI_set_slots.hh | |
parent | 530350935472970dccc211b0e728e2db4fd1d8ef (diff) |
BLI: improve exception safety of Set and Map
For more information see rB2aff45146f1464ba8899368ad004522cb6a1a98c.
Diffstat (limited to 'source/blender/blenlib/BLI_set_slots.hh')
-rw-r--r-- | source/blender/blenlib/BLI_set_slots.hh | 47 |
1 files changed, 8 insertions, 39 deletions
diff --git a/source/blender/blenlib/BLI_set_slots.hh b/source/blender/blenlib/BLI_set_slots.hh index ee5da17fcaf..a4d01dfdb68 100644 --- a/source/blender/blenlib/BLI_set_slots.hh +++ b/source/blender/blenlib/BLI_set_slots.hh @@ -88,7 +88,7 @@ template<typename Key> class SimpleSetSlot { * other slot has to be moved as well. The other slot stays in the state it was in before. Its * optionally stored key remains in a moved-from state. */ - SimpleSetSlot(SimpleSetSlot &&other) noexcept + SimpleSetSlot(SimpleSetSlot &&other) noexcept(std::is_nothrow_move_constructible_v<Key>) { state_ = other.state_; if (other.state_ == Occupied) { @@ -139,19 +139,6 @@ template<typename Key> class SimpleSetSlot { } /** - * Move the other slot into this slot and destruct it. We do destruction here, because this way - * we can avoid a comparison with the state, since we know the slot is occupied. - */ - void relocate_occupied_here(SimpleSetSlot &other, uint64_t UNUSED(hash)) - { - BLI_assert(!this->is_occupied()); - BLI_assert(other.is_occupied()); - state_ = Occupied; - new (&key_buffer_) Key(std::move(*other.key_buffer_)); - other.key_buffer_.ref().~Key(); - } - - /** * Return true, when this slot is occupied and contains a key that compares equal to the given * key. The hash is used by other slot implementations to determine inequality faster. */ @@ -171,8 +158,8 @@ template<typename Key> class SimpleSetSlot { template<typename ForwardKey> void occupy(ForwardKey &&key, uint64_t UNUSED(hash)) { BLI_assert(!this->is_occupied()); - state_ = Occupied; new (&key_buffer_) Key(std::forward<ForwardKey>(key)); + state_ = Occupied; } /** @@ -181,8 +168,8 @@ template<typename Key> class SimpleSetSlot { void remove() { BLI_assert(this->is_occupied()); - state_ = Removed; key_buffer_.ref().~Key(); + state_ = Removed; } }; @@ -224,7 +211,7 @@ template<typename Key> class HashedSetSlot { } } - HashedSetSlot(HashedSetSlot &&other) noexcept + HashedSetSlot(HashedSetSlot &&other) noexcept(std::is_nothrow_move_constructible_v<Key>) { state_ = other.state_; if (other.state_ == Occupied) { @@ -259,16 +246,6 @@ template<typename Key> class HashedSetSlot { return hash_; } - void relocate_occupied_here(HashedSetSlot &other, const uint64_t hash) - { - BLI_assert(!this->is_occupied()); - BLI_assert(other.is_occupied()); - state_ = Occupied; - hash_ = hash; - new (&key_buffer_) Key(std::move(*other.key_buffer_)); - key_buffer_.ref().~Key(); - } - template<typename ForwardKey, typename IsEqual> bool contains(const ForwardKey &key, const IsEqual &is_equal, const uint64_t hash) const { @@ -284,16 +261,16 @@ template<typename Key> class HashedSetSlot { template<typename ForwardKey> void occupy(ForwardKey &&key, const uint64_t hash) { BLI_assert(!this->is_occupied()); + new (&key_buffer_) Key(std::forward<ForwardKey>(key)); state_ = Occupied; hash_ = hash; - new (&key_buffer_) Key(std::forward<ForwardKey>(key)); } void remove() { BLI_assert(this->is_occupied()); - state_ = Removed; key_buffer_.ref().~Key(); + state_ = Removed; } }; @@ -313,7 +290,8 @@ template<typename Key, typename KeyInfo> class IntrusiveSetSlot { IntrusiveSetSlot() = default; ~IntrusiveSetSlot() = default; IntrusiveSetSlot(const IntrusiveSetSlot &other) = default; - IntrusiveSetSlot(IntrusiveSetSlot &&other) noexcept = default; + IntrusiveSetSlot(IntrusiveSetSlot &&other) noexcept(std::is_nothrow_move_constructible_v<Key>) = + default; Key *key() { @@ -341,14 +319,6 @@ template<typename Key, typename KeyInfo> class IntrusiveSetSlot { return hash(key_); } - void relocate_occupied_here(IntrusiveSetSlot &other, const uint64_t UNUSED(hash)) - { - BLI_assert(!this->is_occupied()); - BLI_assert(other.is_occupied()); - key_ = std::move(other.key_); - other.key_.~Key(); - } - template<typename ForwardKey, typename IsEqual> bool contains(const ForwardKey &key, const IsEqual &is_equal, const uint64_t UNUSED(hash)) const { @@ -360,7 +330,6 @@ template<typename Key, typename KeyInfo> class IntrusiveSetSlot { { BLI_assert(!this->is_occupied()); BLI_assert(KeyInfo::is_not_empty_or_removed(key)); - key_ = std::forward<ForwardKey>(key); } |