aboutsummaryrefslogtreecommitdiff
path: root/src/common/Containers
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2024-08-17 12:40:27 +0200
committerShauren <shauren.trinity@gmail.com>2024-08-17 12:40:27 +0200
commitedb20999a3b414ebe1b89410f08f2434e8da1cdb (patch)
treeb12ed325f926bd7a98bd6a4e819c1a5ba6ae933b /src/common/Containers
parent1f952893fc82bc677058737f77de710c426c60ee (diff)
Core/Utils: Unwrap non-copyable pointers (unique_ptr) from Trinity::Containers::MapGetValuePtr
Diffstat (limited to 'src/common/Containers')
-rw-r--r--src/common/Containers/Utilities/MapUtils.h19
1 files changed, 15 insertions, 4 deletions
diff --git a/src/common/Containers/Utilities/MapUtils.h b/src/common/Containers/Utilities/MapUtils.h
index 7cf07243b0a..910f16022a6 100644
--- a/src/common/Containers/Utilities/MapUtils.h
+++ b/src/common/Containers/Utilities/MapUtils.h
@@ -18,6 +18,7 @@
#ifndef TRINITYCORE_MAP_UTILS_H
#define TRINITYCORE_MAP_UTILS_H
+#include <memory> // std::to_address, std::addressof
#include <type_traits>
namespace Trinity::Containers
@@ -26,13 +27,23 @@ namespace Trinity::Containers
* Returns a pointer to mapped value (or the value itself if map stores pointers)
*/
template<class M>
-auto MapGetValuePtr(M& map, typename M::key_type const& key)
+inline auto MapGetValuePtr(M& map, typename M::key_type const& key)
{
+ using mapped_type = typename M::mapped_type;
+
auto itr = map.find(key);
- if constexpr (std::is_pointer_v<typename M::mapped_type>)
- return itr != map.end() ? itr->second : nullptr;
+ if constexpr (std::is_pointer_v<mapped_type>)
+ return itr != map.end() ? std::to_address(itr->second) : nullptr; // raw pointer
+ else if constexpr (requires(mapped_type const& p) { p.operator->(); })
+ {
+ // smart pointers
+ if constexpr (std::is_copy_constructible_v<mapped_type>)
+ return itr != map.end() ? itr->second : nullptr; // copyable (like shared_ptr)
+ else
+ return itr != map.end() ? std::to_address(itr->second) : nullptr; // non-copyable unique_ptr like, unwrap it to raw pointer
+ }
else
- return itr != map.end() ? &itr->second : nullptr;
+ return itr != map.end() ? std::addressof(itr->second) : nullptr; // value
}
template<class K, class V, template<class, class, class...> class M, class... Rest>