UnorderedMap.h 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2024 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #pragma once
  5. #include <Jolt/Core/HashTable.h>
  6. JPH_NAMESPACE_BEGIN
  7. /// Internal helper class to provide context for UnorderedMap
  8. template <class Key, class Value>
  9. class UnorderedMapDetail
  10. {
  11. public:
  12. /// Get key from key value pair
  13. static const Key & sGetKey(const std::pair<Key, Value> &inKeyValue)
  14. {
  15. return inKeyValue.first;
  16. }
  17. };
  18. /// Hash Map class
  19. /// @tparam Key Key type
  20. /// @tparam Value Value type
  21. /// @tparam Hash Hash function (note should be 64-bits)
  22. /// @tparam KeyEqual Equality comparison function
  23. template <class Key, class Value, class Hash = JPH::Hash<Key>, class KeyEqual = std::equal_to<Key>>
  24. class UnorderedMap : public HashTable<Key, std::pair<Key, Value>, UnorderedMapDetail<Key, Value>, Hash, KeyEqual>
  25. {
  26. using Base = HashTable<Key, std::pair<Key, Value>, UnorderedMapDetail<Key, Value>, Hash, KeyEqual>;
  27. public:
  28. using size_type = typename Base::size_type;
  29. using iterator = typename Base::iterator;
  30. using const_iterator = typename Base::const_iterator;
  31. using value_type = typename Base::value_type;
  32. Value & operator [] (const Key &inKey)
  33. {
  34. size_type index;
  35. bool inserted = this->InsertKey(inKey, index);
  36. value_type &key_value = this->GetElement(index);
  37. if (inserted)
  38. new (&key_value) value_type(inKey, Value());
  39. return key_value.second;
  40. }
  41. template<class... Args>
  42. std::pair<iterator, bool> try_emplace(const Key &inKey, Args &&...inArgs)
  43. {
  44. size_type index;
  45. bool inserted = this->InsertKey(inKey, index);
  46. if (inserted)
  47. new (&this->GetElement(index)) value_type(std::piecewise_construct, std::forward_as_tuple(inKey), std::forward_as_tuple(std::forward<Args>(inArgs)...));
  48. return std::make_pair(iterator(this, index), inserted);
  49. }
  50. template<class... Args>
  51. std::pair<iterator, bool> try_emplace(Key &&inKey, Args &&...inArgs)
  52. {
  53. size_type index;
  54. bool inserted = this->InsertKey(inKey, index);
  55. if (inserted)
  56. new (&this->GetElement(index)) value_type(std::piecewise_construct, std::forward_as_tuple(std::move(inKey)), std::forward_as_tuple(std::forward<Args>(inArgs)...));
  57. return std::make_pair(iterator(this, index), inserted);
  58. }
  59. /// Const version of find
  60. using Base::find;
  61. /// Non-const version of find
  62. iterator find(const Key &inKey)
  63. {
  64. const_iterator it = Base::find(inKey);
  65. return iterator(this, it.mIndex);
  66. }
  67. };
  68. JPH_NAMESPACE_END