From 27cd5a90f4c1f34c47cd4e1bd1a616e9b11b10ec Mon Sep 17 00:00:00 2001 From: Shauren Date: Sat, 7 Jan 2023 22:38:21 +0100 Subject: Core/Misc: Replace enable_if overload selection with if constexpr (cherry picked from commit a53e4a57565d3375a978effbbc32d3eed6aac7e3) --- src/common/Containers/Utilities/MapUtils.h | 51 +++++ src/common/Utilities/Containers.h | 76 +++---- src/common/Utilities/Util.cpp | 2 +- src/common/Utilities/Util.h | 19 +- .../game/Chat/ChatCommands/ChatCommandArgs.h | 6 +- .../game/Grids/Dynamic/TypeContainerFunctions.h | 253 +++++++-------------- src/server/scripts/Commands/cs_gobject.cpp | 2 +- src/server/scripts/Commands/cs_npc.cpp | 2 +- 8 files changed, 185 insertions(+), 226 deletions(-) create mode 100644 src/common/Containers/Utilities/MapUtils.h (limited to 'src') diff --git a/src/common/Containers/Utilities/MapUtils.h b/src/common/Containers/Utilities/MapUtils.h new file mode 100644 index 00000000000..7cf07243b0a --- /dev/null +++ b/src/common/Containers/Utilities/MapUtils.h @@ -0,0 +1,51 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef TRINITYCORE_MAP_UTILS_H +#define TRINITYCORE_MAP_UTILS_H + +#include + +namespace Trinity::Containers +{ +/** + * Returns a pointer to mapped value (or the value itself if map stores pointers) + */ +template +auto MapGetValuePtr(M& map, typename M::key_type const& key) +{ + auto itr = map.find(key); + if constexpr (std::is_pointer_v) + return itr != map.end() ? itr->second : nullptr; + else + return itr != map.end() ? &itr->second : nullptr; +} + +template class M, class... Rest> +void MultimapErasePair(M& multimap, K const& key, V const& value) +{ + auto range = multimap.equal_range(key); + for (auto itr = range.first; itr != range.second;) + { + if (itr->second == value) + itr = multimap.erase(itr); + else + ++itr; + } +} +} +#endif // TRINITYCORE_MAP_UTILS_H diff --git a/src/common/Utilities/Containers.h b/src/common/Utilities/Containers.h index 916026b7408..a55602a3163 100644 --- a/src/common/Utilities/Containers.h +++ b/src/common/Utilities/Containers.h @@ -19,6 +19,7 @@ #define TRINITY_CONTAINERS_H #include "Define.h" +#include "MapUtils.h" #include "Random.h" #include #include @@ -29,18 +30,6 @@ namespace Trinity { - template - constexpr inline T* AddressOrSelf(T* ptr) - { - return ptr; - } - - template - constexpr inline T* AddressOrSelf(T& not_ptr) - { - return std::addressof(not_ptr); - } - template class CheckedBufferOutputIterator { @@ -207,55 +196,44 @@ namespace Trinity return false; } - /** - * Returns a pointer to mapped value (or the value itself if map stores pointers) - */ - template - inline auto MapGetValuePtr(M& map, typename M::key_type const& key) -> decltype(AddressOrSelf(map.find(key)->second)) - { - auto itr = map.find(key); - return itr != map.end() ? AddressOrSelf(itr->second) : nullptr; - } - - template class M, class... Rest> - void MultimapErasePair(M& multimap, K const& key, V const& value) + namespace Impl { - auto range = multimap.equal_range(key); - for (auto itr = range.first; itr != range.second;) + template + void EraseIfMoveAssignable(Container& c, Predicate p) { - if (itr->second == value) - itr = multimap.erase(itr); - else - ++itr; + auto wpos = c.begin(); + for (auto rpos = c.begin(), end = c.end(); rpos != end; ++rpos) + { + if (!p(*rpos)) + { + if (rpos != wpos) + std::swap(*rpos, *wpos); + ++wpos; + } + } + c.erase(wpos, c.end()); } - } - template - std::enable_if_t().begin())>, void> EraseIf(Container& c, Predicate p) - { - auto wpos = c.begin(); - for (auto rpos = c.begin(), end = c.end(); rpos != end; ++rpos) + template + void EraseIfNotMoveAssignable(Container& c, Predicate p) { - if (!p(*rpos)) + for (auto it = c.begin(); it != c.end();) { - if (rpos != wpos) - std::swap(*rpos, *wpos); - ++wpos; + if (p(*it)) + it = c.erase(it); + else + ++it; } } - c.erase(wpos, c.end()); } template - std::enable_if_t().begin())>, void> EraseIf(Container& c, Predicate p) + void EraseIf(Container& c, Predicate p) { - for (auto it = c.begin(); it != c.end();) - { - if (p(*it)) - it = c.erase(it); - else - ++it; - } + if constexpr (std::is_move_assignable_v) + Impl::EraseIfMoveAssignable(c, std::ref(p)); + else + Impl::EraseIfNotMoveAssignable(c, std::ref(p)); } } //! namespace Containers diff --git a/src/common/Utilities/Util.cpp b/src/common/Utilities/Util.cpp index 45ab3098e91..4693bd9eb08 100644 --- a/src/common/Utilities/Util.cpp +++ b/src/common/Utilities/Util.cpp @@ -708,7 +708,7 @@ bool StringCompareLessI(std::string_view a, std::string_view b) return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end(), [](char c1, char c2) { return std::tolower(c1) < std::tolower(c2); }); } -std::string GetTypeName(std::type_info const& info) +std::string Trinity::Impl::GetTypeName(std::type_info const& info) { return boost::core::demangle(info.name()); } diff --git a/src/common/Utilities/Util.h b/src/common/Utilities/Util.h index 87dd45d3cbc..d37b86f85e5 100644 --- a/src/common/Utilities/Util.h +++ b/src/common/Utilities/Util.h @@ -557,10 +557,23 @@ Ret* Coalesce(T1* first, T*... rest) return static_cast(first); } -TC_COMMON_API std::string GetTypeName(std::type_info const&); +namespace Trinity +{ +namespace Impl +{ + TC_COMMON_API std::string GetTypeName(std::type_info const&); +} + template -std::string GetTypeName() { return GetTypeName(typeid(T)); } +std::string GetTypeName() { return Impl::GetTypeName(typeid(T)); } template -std::enable_if_t, std::type_info>, std::string> GetTypeName(T&& v) { return GetTypeName(typeid(v)); } +std::string GetTypeName(T&& v) +{ + if constexpr (std::is_same_v, std::type_info>) + return Impl::GetTypeName(v); + else + return Impl::GetTypeName(typeid(v)); +} +} #endif diff --git a/src/server/game/Chat/ChatCommands/ChatCommandArgs.h b/src/server/game/Chat/ChatCommands/ChatCommandArgs.h index 4b36b28b26d..71d115923ab 100644 --- a/src/server/game/Chat/ChatCommands/ChatCommandArgs.h +++ b/src/server/game/Chat/ChatCommands/ChatCommandArgs.h @@ -62,12 +62,12 @@ namespace Trinity::Impl::ChatCommands if (Optional v = StringTo(token, 0)) val = *v; else - return FormatTrinityString(handler, LANG_CMDPARSER_STRING_VALUE_INVALID, STRING_VIEW_FMT_ARG(token), GetTypeName().c_str()); + return FormatTrinityString(handler, LANG_CMDPARSER_STRING_VALUE_INVALID, STRING_VIEW_FMT_ARG(token), Trinity::GetTypeName().c_str()); if constexpr (std::is_floating_point_v) { if (!std::isfinite(val)) - return FormatTrinityString(handler, LANG_CMDPARSER_STRING_VALUE_INVALID, STRING_VIEW_FMT_ARG(token), GetTypeName().c_str()); + return FormatTrinityString(handler, LANG_CMDPARSER_STRING_VALUE_INVALID, STRING_VIEW_FMT_ARG(token), Trinity::GetTypeName().c_str()); } return tail; @@ -200,7 +200,7 @@ namespace Trinity::Impl::ChatCommands } if (next1) - return FormatTrinityString(handler, LANG_CMDPARSER_STRING_VALUE_INVALID, STRING_VIEW_FMT_ARG(strVal), GetTypeName().c_str()); + return FormatTrinityString(handler, LANG_CMDPARSER_STRING_VALUE_INVALID, STRING_VIEW_FMT_ARG(strVal), Trinity::GetTypeName().c_str()); else return next1; } diff --git a/src/server/game/Grids/Dynamic/TypeContainerFunctions.h b/src/server/game/Grids/Dynamic/TypeContainerFunctions.h index 94d9a7e1594..6a614e94eb6 100644 --- a/src/server/game/Grids/Dynamic/TypeContainerFunctions.h +++ b/src/server/game/Grids/Dynamic/TypeContainerFunctions.h @@ -33,210 +33,127 @@ namespace Trinity { // Helpers // Insert helpers - template - bool Insert(ContainerUnorderedMap& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* obj) + template + inline bool Insert(ContainerUnorderedMap, KEY_TYPE>& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* obj) { - auto i = elements._element.find(handle); - if (i == elements._element.end()) + if constexpr (std::is_same_v) { - elements._element[handle] = obj; - return true; + auto i = elements._elements._element.find(handle); + if (i == elements._elements._element.end()) + { + elements._elements._element[handle] = obj; + return true; + } + else + { + ASSERT(i->second == obj, "Object with certain key already in but objects are different!"); + return false; + } } - else - { - ASSERT(i->second == obj, "Object with certain key already in but objects are different!"); - return false; - } - } - template - bool Insert(ContainerUnorderedMap& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/) - { - return false; - } - - template - bool Insert(ContainerUnorderedMap& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/) - { - return false; + if constexpr (std::is_same_v) + return false; + else + return Insert(elements._TailElements, handle, obj); } + // Find helpers template - bool Insert(ContainerUnorderedMap, KEY_TYPE>& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* obj) + inline SPECIFIC_TYPE* Find(ContainerUnorderedMap, KEY_TYPE> const& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* obj) { - bool ret = Insert(elements._elements, handle, obj); - return ret ? ret : Insert(elements._TailElements, handle, obj); - } + if constexpr (std::is_same_v) + { + auto i = elements._elements._element.find(handle); + if (i == elements._elements._element.end()) + return nullptr; + else + return i->second; + } - // Find helpers - template - SPECIFIC_TYPE* Find(ContainerUnorderedMap const& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* /*obj*/) - { - auto i = elements._element.find(handle); - if (i == elements._element.end()) + if constexpr (std::is_same_v) return nullptr; else - return i->second; - } - - template - SPECIFIC_TYPE* Find(ContainerUnorderedMap const& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/) - { - return nullptr; - } - - template - SPECIFIC_TYPE* Find(ContainerUnorderedMap const& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/) - { - return nullptr; - } - - template - SPECIFIC_TYPE* Find(ContainerUnorderedMap, KEY_TYPE> const& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* /*obj*/) - { - SPECIFIC_TYPE* ret = Find(elements._elements, handle, (SPECIFIC_TYPE*)nullptr); - return ret ? ret : Find(elements._TailElements, handle, (SPECIFIC_TYPE*)nullptr); + return Find(elements._TailElements, handle, obj); } // Erase helpers - template - bool Remove(ContainerUnorderedMap& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* /*obj*/) - { - elements._element.erase(handle); - return true; - } - - template - bool Remove(ContainerUnorderedMap& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/) - { - return false; - } - - template - bool Remove(ContainerUnorderedMap& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/) - { - return false; - } - template - bool Remove(ContainerUnorderedMap, KEY_TYPE>& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* /*obj*/) - { - bool ret = Remove(elements._elements, handle, (SPECIFIC_TYPE*)nullptr); - return ret ? ret : Remove(elements._TailElements, handle, (SPECIFIC_TYPE*)nullptr); - } - - // Count helpers - template - bool Size(ContainerUnorderedMap const& elements, std::size_t* size, SPECIFIC_TYPE* /*obj*/) - { - *size = elements._element.size(); - return true; - } - - template - bool Size(ContainerUnorderedMap const& /*elements*/, std::size_t* /*size*/, SPECIFIC_TYPE* /*obj*/) + inline bool Remove(ContainerUnorderedMap, KEY_TYPE>& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* obj) { - return false; - } + if constexpr (std::is_same_v) + { + elements._elements._element.erase(handle); + return true; + } - template - bool Size(ContainerUnorderedMap const& /*elements*/, std::size_t* /*size*/, SPECIFIC_TYPE* /*obj*/) - { - return false; + if constexpr (std::is_same_v) + return false; + else + return Remove(elements._TailElements, handle, obj); } + // Count helpers template - bool Size(ContainerUnorderedMap, KEY_TYPE> const& elements, std::size_t* size, SPECIFIC_TYPE* /*obj*/) + inline bool Size(ContainerUnorderedMap, KEY_TYPE> const& elements, std::size_t* size, SPECIFIC_TYPE* obj) { - bool ret = Size(elements._elements, size, (SPECIFIC_TYPE*)nullptr); - return ret ? ret : Size(elements._TailElements, size, (SPECIFIC_TYPE*)nullptr); + if constexpr (std::is_same_v) + { + *size = elements._elements._element.size(); + return true; + } + + if constexpr (std::is_same_v) + return false; + else + return Size(elements._TailElements, size, obj); } /* ContainerMapList Helpers */ // count functions - template - size_t Count(ContainerMapList const& elements, SPECIFIC_TYPE* /*fake*/) - { - return elements._element.getSize(); - } - - template - size_t Count(ContainerMapList const& /*elements*/, SPECIFIC_TYPE* /*fake*/) - { - return 0; - } - - template - size_t Count(ContainerMapList const& /*elements*/, SPECIFIC_TYPE* /*fake*/) - { - return 0; - } - - template - size_t Count(ContainerMapList> const& elements, SPECIFIC_TYPE* fake) - { - return Count(elements._elements, fake); - } - template - size_t Count(ContainerMapList> const& elements, SPECIFIC_TYPE* fake) + inline size_t Count(ContainerMapList> const& elements, SPECIFIC_TYPE* fake) { - return Count(elements._TailElements, fake); - } - - // non-const insert functions - template - SPECIFIC_TYPE* Insert(ContainerMapList& elements, SPECIFIC_TYPE* obj) - { - //elements._element[hdl] = obj; - obj->AddToGrid(elements._element); - return obj; - } - - template - SPECIFIC_TYPE* Insert(ContainerMapList& /*elements*/, SPECIFIC_TYPE* /*obj*/) - { - return nullptr; - } + if constexpr (std::is_same_v) + { + return elements._elements._element.getSize(); + } - // this is a missed - template - SPECIFIC_TYPE* Insert(ContainerMapList& /*elements*/, SPECIFIC_TYPE* /*obj*/) - { - return nullptr; // a missed + if constexpr (std::is_same_v) + return 0; + else + return Count(elements._TailElements, fake); } - // Recursion + // non-const insert functions template - SPECIFIC_TYPE* Insert(ContainerMapList>& elements, SPECIFIC_TYPE* obj) + inline SPECIFIC_TYPE* Insert(ContainerMapList>& elements, SPECIFIC_TYPE* obj) { - SPECIFIC_TYPE* t = Insert(elements._elements, obj); - return (t != nullptr ? t : Insert(elements._TailElements, obj)); + if constexpr (std::is_same_v) + { + obj->AddToGrid(elements._elements._element); + return obj; + } + + if constexpr (std::is_same_v) + return nullptr; + else + return Insert(elements._TailElements, obj); } //// non-const remove method - //template SPECIFIC_TYPE* Remove(ContainerMapList & /*elements*/, SPECIFIC_TYPE *obj) - //{ - // obj->GetGridRef().unlink(); - // return obj; - //} - - //template SPECIFIC_TYPE* Remove(ContainerMapList &/*elements*/, SPECIFIC_TYPE * /*obj*/) - //{ - // return nullptr; - //} - - //// this is a missed - //template SPECIFIC_TYPE* Remove(ContainerMapList &/*elements*/, SPECIFIC_TYPE * /*obj*/) - //{ - // return nullptr; // a missed - //} - - //template SPECIFIC_TYPE* Remove(ContainerMapList > &elements, SPECIFIC_TYPE *obj) + //template + //SPECIFIC_TYPE* Remove(ContainerMapList>& elements, SPECIFIC_TYPE* obj) //{ - // // The head element is bad - // SPECIFIC_TYPE* t = Remove(elements._elements, obj); - // return (t != nullptr ? t : Remove(elements._TailElements, obj)); + // if constexpr (std::is_same_v) + // { + // obj->GetGridRef().unlink(); + // return obj; + // } + + // if constexpr (std::is_same_v) + // return nullptr; + // else + // return Remove(elements._TailElements, obj); //} } #endif diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp index 806b195924b..0293ae9a93c 100644 --- a/src/server/scripts/Commands/cs_gobject.cpp +++ b/src/server/scripts/Commands/cs_gobject.cpp @@ -577,7 +577,7 @@ public: handler->PSendSysMessage(LANG_GOINFO_SIZE, gameObjectInfo->size); handler->PSendSysMessage(LANG_OBJECTINFO_AIINFO, gameObjectInfo->AIName.c_str(), sObjectMgr->GetScriptName(gameObjectInfo->ScriptId).c_str()); if (GameObjectAI const* ai = thisGO ? thisGO->AI() : nullptr) - handler->PSendSysMessage(LANG_OBJECTINFO_AITYPE, GetTypeName(*ai).c_str()); + handler->PSendSysMessage(LANG_OBJECTINFO_AITYPE, Trinity::GetTypeName(*ai).c_str()); if (GameObjectDisplayInfoEntry const* modelInfo = sGameObjectDisplayInfoStore.LookupEntry(displayId)) handler->PSendSysMessage(LANG_GOINFO_MODEL, modelInfo->GeoBoxMax.X, modelInfo->GeoBoxMax.Y, modelInfo->GeoBoxMax.Z, modelInfo->GeoBoxMin.X, modelInfo->GeoBoxMin.Y, modelInfo->GeoBoxMin.Z); diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index e4ee87db7b6..b2c6cef3229 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -509,7 +509,7 @@ public: handler->PSendSysMessage(LANG_OBJECTINFO_AIINFO, target->GetAIName().c_str(), target->GetScriptName().c_str()); handler->PSendSysMessage(LANG_NPCINFO_REACTSTATE, DescribeReactState(target->GetReactState())); if (CreatureAI const* ai = target->AI()) - handler->PSendSysMessage(LANG_OBJECTINFO_AITYPE, GetTypeName(*ai).c_str()); + handler->PSendSysMessage(LANG_OBJECTINFO_AITYPE, Trinity::GetTypeName(*ai).c_str()); handler->PSendSysMessage(LANG_NPCINFO_FLAGS_EXTRA, cInfo->flags_extra); for (CreatureFlagsExtra flag : EnumUtils::Iterate()) if (cInfo->flags_extra & flag) -- cgit v1.2.3