Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2020-08-24 18:24:13 +0300
committerJacques Lucke <jacques@blender.org>2020-08-24 18:24:13 +0300
commit8e18a9984505514a229d66b38fff31d930367968 (patch)
tree97bb3e6f766e997df712bf081e05e027648e2c28 /source/blender/blenlib/BLI_set_slots.hh
parent530350935472970dccc211b0e728e2db4fd1d8ef (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.hh47
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);
}