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:
Diffstat (limited to 'source/blender/blenlib/BLI_set.hh')
-rw-r--r--source/blender/blenlib/BLI_set.hh35
1 files changed, 34 insertions, 1 deletions
diff --git a/source/blender/blenlib/BLI_set.hh b/source/blender/blenlib/BLI_set.hh
index 9684f372db7..06b56c3f8e5 100644
--- a/source/blender/blenlib/BLI_set.hh
+++ b/source/blender/blenlib/BLI_set.hh
@@ -48,7 +48,7 @@
* - Small buffer optimization is enabled by default, if the key is not too large.
* - The methods `add_new` and `remove_contained` should be used instead of `add` and `remove`
* whenever appropriate. Assumptions and intention are described better this way.
- * - Look-ups can be performed using types other than Key without conversion. For that use the
+ * - Lookups can be performed using types other than Key without conversion. For that use the
* methods ending with `_as`. The template parameters Hash and #IsEqual have to support the other
* key type. This can greatly improve performance when the set contains strings.
* - The default constructor is cheap, even when a large #InlineBufferCapacity is used. A large
@@ -351,6 +351,23 @@ class Set {
}
/**
+ * Returns the key in the set that compares equal to the given key. If it does not exist, the key
+ * is newly added.
+ */
+ const Key &lookup_key_or_add(const Key &key)
+ {
+ return this->lookup_key_or_add_as(key);
+ }
+ const Key &lookup_key_or_add(Key &&key)
+ {
+ return this->lookup_key_or_add_as(std::move(key));
+ }
+ template<typename ForwardKey> const Key &lookup_key_or_add_as(ForwardKey &&key)
+ {
+ return this->lookup_key_or_add__impl(std::forward<ForwardKey>(key), hash_(key));
+ }
+
+ /**
* Deletes the key from the set. Returns true when the key did exist beforehand, otherwise false.
*
* This is similar to std::unordered_set::erase.
@@ -735,6 +752,22 @@ class Set {
}
template<typename ForwardKey>
+ const Key &lookup_key_or_add__impl(ForwardKey &&key, const uint64_t hash)
+ {
+ SET_SLOT_PROBING_BEGIN (hash, slot) {
+ if (slot.contains(key, is_equal_, hash)) {
+ return *slot.key();
+ }
+ if (slot.is_empty()) {
+ slot.occupy(std::forward<ForwardKey>(key), hash);
+ occupied_and_removed_slots_++;
+ return *slot.key();
+ }
+ }
+ SET_SLOT_PROBING_END();
+ }
+
+ template<typename ForwardKey>
int64_t count_collisions__impl(const ForwardKey &key, const uint64_t hash) const
{
int64_t collisions = 0;