aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTreeston <treeston.mmoc@gmail.com>2020-08-17 02:23:38 +0200
committerGitHub <noreply@github.com>2020-08-17 02:23:38 +0200
commitffc3e355fe2adfe48d37759091a537b699b12753 (patch)
treea8b4745100850e0dc37fa077e327e8bd8814cd5b /src
parent7bceff1b2aa463f8e28277cc8c6eb2eda1952bb4 (diff)
Core/ChatCommands: Move Trinity::ChatCommands::Variant from boost::variant to std::variant (for real this time)
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Chat/ChatCommands/ChatCommandArgs.cpp29
-rw-r--r--src/server/game/Chat/ChatCommands/ChatCommandArgs.h8
-rw-r--r--src/server/game/Chat/ChatCommands/ChatCommandHelpers.h76
-rw-r--r--src/server/game/Chat/ChatCommands/ChatCommandTags.h236
-rw-r--r--src/server/game/Chat/Hyperlinks.h355
5 files changed, 352 insertions, 352 deletions
diff --git a/src/server/game/Chat/ChatCommands/ChatCommandArgs.cpp b/src/server/game/Chat/ChatCommands/ChatCommandArgs.cpp
index 62ed5afc6c2..fb94f6811b3 100644
--- a/src/server/game/Chat/ChatCommands/ChatCommandArgs.cpp
+++ b/src/server/game/Chat/ChatCommands/ChatCommandArgs.cpp
@@ -31,9 +31,9 @@ struct AchievementVisitor
};
char const* Trinity::ChatCommands::ArgInfo<AchievementEntry const*>::TryConsume(AchievementEntry const*& data, char const* args)
{
- Variant <Hyperlink<achievement>, uint32> val;
+ Variant<Hyperlink<achievement>, uint32> val;
if ((args = CommandArgsConsumerSingle<decltype(val)>::TryConsumeTo(val, args)))
- data = boost::apply_visitor(AchievementVisitor(), val);
+ data = val.visit(AchievementVisitor());
return args;
}
@@ -47,7 +47,7 @@ char const* Trinity::ChatCommands::ArgInfo<GameTele const*>::TryConsume(GameTele
{
Variant<Hyperlink<tele>, std::string> val;
if ((args = CommandArgsConsumerSingle<decltype(val)>::TryConsumeTo(val, args)))
- data = boost::apply_visitor(GameTeleVisitor(), val);
+ data = val.visit(GameTeleVisitor());
return args;
}
@@ -61,21 +61,22 @@ char const* Trinity::ChatCommands::ArgInfo<SpellInfo const*>::TryConsume(SpellIn
{
Variant<Hyperlink<spell>, uint32> val;
if ((args = CommandArgsConsumerSingle<decltype(val)>::TryConsumeTo(val, args)))
- data = boost::apply_visitor(SpellInfoVisitor(), val);
+ data = val.visit(SpellInfoVisitor());
return args;
}
-struct BoolVisitor
-{
- using value_type = bool;
- value_type operator()(uint32 i) const { return !!i; }
- value_type operator()(ExactSequence<'o', 'n'>) const { return true; }
- value_type operator()(ExactSequence<'o', 'f', 'f'>) const { return false; }
-};
char const* Trinity::ChatCommands::ArgInfo<bool>::TryConsume(bool& data, char const* args)
{
- Variant<uint32, ExactSequence<'o', 'n'>, ExactSequence<'o', 'f', 'f'>> val;
- if ((args = CommandArgsConsumerSingle<decltype(val)>::TryConsumeTo(val, args)))
- data = boost::apply_visitor(BoolVisitor(), val);
+ std::string val;
+ if ((args = CommandArgsConsumerSingle<std::string>::TryConsumeTo(val, args)))
+ {
+ strToLower(val);
+ if (val == "on" || val == "yes" || val == "true" || val == "1" || val == "y")
+ data = true;
+ else if (val == "off" || val == "no" || val == "false" || val == "0" || val == "n")
+ data = false;
+ else
+ return nullptr;
+ }
return args;
}
diff --git a/src/server/game/Chat/ChatCommands/ChatCommandArgs.h b/src/server/game/Chat/ChatCommands/ChatCommandArgs.h
index c9e0723fbf8..d7fa5cf65db 100644
--- a/src/server/game/Chat/ChatCommands/ChatCommandArgs.h
+++ b/src/server/game/Chat/ChatCommands/ChatCommandArgs.h
@@ -50,7 +50,7 @@ struct ArgInfo<T, std::enable_if_t<std::is_integral_v<T> && std::is_signed_v<T>>
static char const* TryConsume(T& val, char const* args)
{
char const* next = args;
- std::string token(args, tokenize(next));
+ std::string token(args, Trinity::Impl::ChatCommands::tokenize(next));
try
{
size_t processedChars = 0;
@@ -70,7 +70,7 @@ struct ArgInfo<T, std::enable_if_t<std::is_integral_v<T> && std::is_unsigned_v<T
static char const* TryConsume(T& val, char const* args)
{
char const* next = args;
- std::string token(args, tokenize(next));
+ std::string token(args, Trinity::Impl::ChatCommands::tokenize(next));
try
{
size_t processedChars = 0;
@@ -90,7 +90,7 @@ struct ArgInfo<T, std::enable_if_t<std::is_floating_point_v<T>>>
static char const* TryConsume(T& val, char const* args)
{
char const* next = args;
- std::string token(args, tokenize(next));
+ std::string token(args, Trinity::Impl::ChatCommands::tokenize(next));
try
{
size_t processedChars = 0;
@@ -110,7 +110,7 @@ struct ArgInfo<std::string, void>
static char const* TryConsume(std::string& val, char const* args)
{
char const* next = args;
- if (size_t len = tokenize(next))
+ if (size_t len = Trinity::Impl::ChatCommands::tokenize(next))
{
val.assign(args, len);
return next;
diff --git a/src/server/game/Chat/ChatCommands/ChatCommandHelpers.h b/src/server/game/Chat/ChatCommands/ChatCommandHelpers.h
index ff9b5a3b8fc..e22823e5d35 100644
--- a/src/server/game/Chat/ChatCommands/ChatCommandHelpers.h
+++ b/src/server/game/Chat/ChatCommands/ChatCommandHelpers.h
@@ -20,58 +20,50 @@
#include <type_traits>
-namespace Trinity
-{
-namespace ChatCommands
+namespace Trinity::ChatCommands
{
+ static constexpr char COMMAND_DELIMITER = ' ';
-static constexpr char COMMAND_DELIMITER = ' ';
+ template <typename T, typename = void>
+ struct tag_base
+ {
+ using type = T;
+ };
-/***************** HELPERS *************************\
-|* These really aren't for outside use... *|
-\***************************************************/
-inline std::size_t tokenize(char const*& end)
-{
- std::size_t len = 0;
- for (; *end && *end != COMMAND_DELIMITER; ++end, ++len);
- for (; *end && *end == COMMAND_DELIMITER; ++end);
- return len;
+ template <typename T>
+ using tag_base_t = typename tag_base<T>::type;
}
-template <typename T, typename = void>
-struct tag_base
+namespace Trinity::Impl::ChatCommands
{
- using type = T;
-};
+ /***************** HELPERS *************************\
+ |* These really aren't for outside use... *|
+ \***************************************************/
+ inline std::size_t tokenize(char const*& end)
+ {
+ std::size_t len = 0;
+ for (; *end && *end != Trinity::ChatCommands::COMMAND_DELIMITER; ++end, ++len);
+ for (; *end && *end == Trinity::ChatCommands::COMMAND_DELIMITER; ++end);
+ return len;
+ }
-template <typename T>
-using tag_base_t = typename tag_base<T>::type;
+ template <typename T, typename... Ts>
+ struct are_all_assignable
+ {
+ static constexpr bool value = (std::is_assignable_v<T&, Ts> && ...);
+ };
-template <typename...>
-struct are_all_assignable
-{
- static constexpr bool value = true;
-};
-
-template <typename T1, typename T2, typename... Ts>
-struct are_all_assignable<T1, T2, Ts...>
-{
- static constexpr bool value = std::is_assignable_v<T1&, T2> && are_all_assignable<T1, Ts...>::value;
-};
+ template <std::size_t index, typename T1, typename... Ts>
+ struct get_nth : get_nth<index-1, Ts...> { };
-template <std::size_t index, typename T1, typename... Ts>
-struct get_nth : get_nth<index-1, Ts...> { };
+ template <typename T1, typename... Ts>
+ struct get_nth<0, T1, Ts...>
+ {
+ using type = T1;
+ };
-template <typename T1, typename... Ts>
-struct get_nth<0, T1, Ts...>
-{
- using type = T1;
-};
-
-template <std::size_t index, typename... Ts>
-using get_nth_t = typename get_nth<index, Ts...>::type;
-
-}
+ template <std::size_t index, typename... Ts>
+ using get_nth_t = typename get_nth<index, Ts...>::type;
}
#endif
diff --git a/src/server/game/Chat/ChatCommands/ChatCommandTags.h b/src/server/game/Chat/ChatCommands/ChatCommandTags.h
index feffc25aa25..ba4f6d5a649 100644
--- a/src/server/game/Chat/ChatCommands/ChatCommandTags.h
+++ b/src/server/game/Chat/ChatCommands/ChatCommandTags.h
@@ -22,150 +22,160 @@
#include "ChatCommandHelpers.h"
#include "Hyperlinks.h"
#include "Optional.h"
-#include <boost/variant.hpp>
#include <cmath>
#include <cstring>
+#include <iostream>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>
+#include <variant>
-namespace Trinity
+namespace Trinity::ChatCommands
{
-namespace ChatCommands
-{
-/************************** CONTAINER TAGS **********************************************\
-|* Simple holder classes to differentiate between extraction methods *|
-|* Should inherit from ContainerTag for template identification *|
-|* Must implement the following: *|
-|* - TryConsume: char const* -> char const* *|
-|* returns nullptr if no match, otherwise pointer to first character of next token *|
-|* - typedef value_type of type that is contained within the tag *|
-|* - cast operator to value_type *|
-|* *|
-\****************************************************************************************/
-struct ContainerTag {};
-template <typename T>
-struct tag_base<T, std::enable_if_t<std::is_base_of_v<ContainerTag, T>>>
-{
- using type = typename T::value_type;
-};
-
-template <char c1, char... chars>
-struct ExactSequence : public ContainerTag
-{
- using value_type = void;
-
- static constexpr bool isSingleChar = !sizeof...(chars);
-
- template <bool C = isSingleChar>
- static typename std::enable_if_t<!C, char const*> _TryConsume(char const* pos)
+ /************************** CONTAINER TAGS **********************************************\
+ |* Simple holder classes to differentiate between extraction methods *|
+ |* Should inherit from ContainerTag for template identification *|
+ |* Must implement the following: *|
+ |* - TryConsume: char const* -> char const* *|
+ |* returns nullptr if no match, otherwise pointer to first character of next token *|
+ |* - typedef value_type of type that is contained within the tag *|
+ |* - cast operator to value_type *|
+ |* *|
+ \****************************************************************************************/
+ struct ContainerTag {};
+ template <typename T>
+ struct tag_base<T, std::enable_if_t<std::is_base_of_v<ContainerTag, T>>>
{
- if (*(pos++) == c1)
- return ExactSequence<chars...>::_TryConsume(pos);
- else
- return nullptr;
- }
+ using type = typename T::value_type;
+ };
- template <bool C = isSingleChar>
- static typename std::enable_if_t<C, char const*> _TryConsume(char const* pos)
+ template <char c1, char... chars>
+ struct ExactSequence : public ContainerTag
{
- if (*(pos++) != c1)
- return nullptr;
- // if more of string is left, tokenize should return 0 (otherwise we didn't reach end of token yet)
- return *pos && tokenize(pos) ? nullptr : pos;
- }
-
- char const* TryConsume(char const* pos) const { return ExactSequence::_TryConsume(pos); }
-};
-
-template <typename linktag>
-struct Hyperlink : public ContainerTag
-{
- typedef typename linktag::value_type value_type;
- typedef advstd::remove_cvref_t<value_type> storage_type;
-
- public:
- operator value_type() const { return val; }
- value_type operator*() const { return val; }
- storage_type const* operator->() const { return &val; }
+ using value_type = void;
- char const* TryConsume(char const* pos)
+ static char const* _TryConsume(char const* pos)
{
- Trinity::Hyperlinks::HyperlinkInfo info = Trinity::Hyperlinks::ParseHyperlink(pos);
- // invalid hyperlinks cannot be consumed
- if (!info)
- return nullptr;
-
- // check if we got the right tag
- if (info.tag.second != strlen(linktag::tag()))
- return nullptr;
- if (strncmp(info.tag.first, linktag::tag(), strlen(linktag::tag())) != 0)
+ if (*(pos++) == c1)
+ {
+ if constexpr (sizeof...(chars))
+ return ExactSequence<chars...>::_TryConsume(pos);
+ else if (Trinity::Impl::ChatCommands::tokenize(pos)) /* we did not consume the entire token */
+ return nullptr;
+ else
+ return pos;
+ }
+ else
return nullptr;
-
- // store value
- if (!linktag::StoreTo(val, info.data.first, info.data.second))
- return nullptr;
-
- // finally, skip to end of token
- pos = info.next;
- tokenize(pos);
-
- // return final pos
- return pos;
}
- private:
- storage_type val;
-};
+ char const* TryConsume(char const* pos) const { return ExactSequence::_TryConsume(pos); }
+ };
-// pull in link tags for user convenience
-using namespace ::Trinity::Hyperlinks::LinkTags;
+ template <typename linktag>
+ struct Hyperlink : public ContainerTag
+ {
+ using value_type = typename linktag::value_type;
+ using storage_type = advstd::remove_cvref_t<value_type>;
+
+ public:
+ operator value_type() const { return val; }
+ value_type operator*() const { return val; }
+ storage_type const* operator->() const { return &val; }
+
+ char const* TryConsume(char const* pos)
+ {
+ Trinity::Hyperlinks::HyperlinkInfo info = Trinity::Hyperlinks::ParseHyperlink(pos);
+ // invalid hyperlinks cannot be consumed
+ if (!info)
+ return nullptr;
+
+ // check if we got the right tag
+ if (info.tag.second != strlen(linktag::tag()))
+ return nullptr;
+ if (strncmp(info.tag.first, linktag::tag(), strlen(linktag::tag())) != 0)
+ return nullptr;
+
+ // store value
+ if (!linktag::StoreTo(val, info.data.first, info.data.second))
+ return nullptr;
+
+ // finally, skip to end of token
+ pos = info.next;
+ Trinity::Impl::ChatCommands::tokenize(pos);
+
+ // return final pos
+ return pos;
+ }
+
+ private:
+ storage_type val;
+ };
+
+ // pull in link tags for user convenience
+ using namespace ::Trinity::Hyperlinks::LinkTags;
+}
/************************** VARIANT TAG LOGIC *********************************\
|* This has some special handling over in ChatCommand.h *|
\******************************************************************************/
-template <typename T>
-struct CastToVisitor {
- using result_type = T;
-
- template <typename U>
- T operator()(U const& v) const { return v; }
-};
-
-template <typename T1, typename... Ts>
-struct Variant : public boost::variant<T1, Ts...>
+namespace Trinity::Impl
{
- using first_type = tag_base_t<T1>;
- static constexpr bool have_operators = are_all_assignable<first_type, tag_base_t<Ts>...>::value;
+ template <typename T>
+ struct CastToVisitor {
+ template <typename U>
+ T operator()(U const& v) const { return v; }
+ };
+}
- template <bool C = have_operators>
- operator std::enable_if_t<C, first_type>()
+namespace Trinity::ChatCommands
+{
+ template <typename T1, typename... Ts>
+ struct Variant : public std::variant<T1, Ts...>
{
- return operator*();
- }
+ using base = std::variant<T1, Ts...>;
- template <bool C = have_operators>
- std::enable_if_t<C, first_type> operator*()
- {
- return boost::apply_visitor(CastToVisitor<first_type>(), *this);
- }
+ using first_type = tag_base_t<T1>;
+ static constexpr bool have_operators = Trinity::Impl::ChatCommands::are_all_assignable<first_type, tag_base_t<Ts>...>::value;
- template <bool C = have_operators>
- std::enable_if_t<C, first_type const&> operator*() const
- {
- return boost::apply_visitor(CastToVisitor<first_type const&>(), *this);
- }
+ template <bool C = have_operators>
+ std::enable_if_t<C, first_type> operator*() const
+ {
+ return visit(Trinity::Impl::CastToVisitor<first_type>());
+ }
- template <typename T>
- Variant& operator=(T&& arg) { boost::variant<T1, Ts...>::operator=(std::forward<T>(arg)); return *this; }
+ template <bool C = have_operators>
+ operator std::enable_if_t<C, first_type>() const
+ {
+ return operator*();
+ }
+
+ template <typename T>
+ Variant& operator=(T&& arg) { base::operator=(std::forward<T>(arg)); return *this; }
- template <size_t index>
- decltype(auto) get() const { return boost::get<get_nth_t<index, T1, Ts...>>(*this); }
-};
+ template <size_t index>
+ constexpr decltype(auto) get() { return std::get<index>(static_cast<base const&>(*this)); }
+ template <size_t index>
+ constexpr decltype(auto) get() const { return std::get<index>(static_cast<base const&>(*this)); }
+ template <typename T>
+ constexpr decltype(auto) visit(T&& arg) const { return std::visit(std::forward<T>(arg), static_cast<base const&>(*this)); }
+
+ template <typename T>
+ constexpr bool holds_alternative() const { return std::holds_alternative<T>(static_cast<base const&>(*this)); }
+ };
}
+
+/* make the correct operator<< to use explicit, because otherwise the compiler gets confused with the implicit std::variant conversion */
+namespace std
+{
+ template <typename... Ts>
+ auto operator<<(std::ostream& os, Trinity::ChatCommands::Variant<Ts...> const& v) -> std::enable_if_t<Trinity::ChatCommands::Variant<Ts...>::have_operators, std::ostream&>
+ {
+ return (os << *v);
+ }
}
#endif
diff --git a/src/server/game/Chat/Hyperlinks.h b/src/server/game/Chat/Hyperlinks.h
index 58d5816c6d3..b1b43b69a07 100644
--- a/src/server/game/Chat/Hyperlinks.h
+++ b/src/server/game/Chat/Hyperlinks.h
@@ -31,212 +31,209 @@ class SpellInfo;
class Quest;
struct TalentEntry;
-namespace Trinity
+namespace Trinity::Hyperlinks
{
-namespace Hyperlinks
-{
-
-struct AchievementLinkData
-{
- AchievementEntry const* Achievement;
- ObjectGuid::LowType CharacterId;
- bool IsFinished;
- uint16 Year;
- uint8 Month;
- uint8 Day;
- uint32 Criteria[4];
-};
-
-struct GlyphLinkData
-{
- GlyphPropertiesEntry const* Glyph;
- GlyphSlotEntry const* Slot;
-};
-
-struct ItemLinkData
-{
- ItemTemplate const* Item;
- uint32 EnchantId;
- uint32 GemEnchantId[3];
- int32 RandomPropertyId;
- int32 RandomPropertySeed;
- uint8 RenderLevel;
-};
-
-struct QuestLinkData
-{
- ::Quest const* Quest;
- uint8 QuestLevel;
-};
-struct TalentLinkData
-{
- TalentEntry const* Talent;
- uint8 Rank;
-};
-
-struct TradeskillLinkData
-{
- SpellInfo const* Spell;
- uint16 CurValue;
- uint16 MaxValue;
- ObjectGuid Owner;
- std::string KnownRecipes;
-};
-
-namespace LinkTags {
-
- /************************** LINK TAGS ***************************************************\
- |* Link tags must abide by the following: *|
- |* - MUST expose ::value_type typedef *|
- |* - storage type is remove_cvref_t<value_type> *|
- |* - MUST expose static ::tag method, void -> const char* *|
- |* - this method SHOULD be constexpr *|
- |* - returns identifier string for the link ("creature", "creature_entry", "item") *|
- |* - MUST expose static ::StoreTo method, (storage&, char const*, size_t) *|
- |* - assign value_type& based on content of std::string(char const*, size_t) *|
- |* - return value indicates success/failure *|
- |* - for integral/string types this can be achieved by extending base_tag *|
- \****************************************************************************************/
- struct base_tag
+ struct AchievementLinkData
{
- static bool StoreTo(std::string& val, char const* pos, size_t len)
- {
- val.assign(pos, len);
- return true;
- }
-
- template <typename T>
- static std::enable_if_t<std::is_integral_v<T> && std::is_unsigned_v<T>, bool> StoreTo(T& val, char const* pos, size_t len)
- {
- try { val = std::stoull(std::string(pos, len)); }
- catch (...) { return false; }
- return true;
- }
-
- template <typename T>
- static std::enable_if_t<std::is_integral_v<T> && std::is_signed_v<T>, bool> StoreTo(T& val, char const* pos, size_t len)
- {
- try { val = std::stoll(std::string(pos, len)); }
- catch (...) { return false; }
- return true;
- }
-
- static bool StoreTo(ObjectGuid& val, char const* pos, size_t len)
- {
- try { val.Set(std::stoul(std::string(pos, len), nullptr, 16)); }
- catch (...) { return false; }
- return true;
- }
+ AchievementEntry const* Achievement;
+ ObjectGuid::LowType CharacterId;
+ bool IsFinished;
+ uint16 Year;
+ uint8 Month;
+ uint8 Day;
+ uint32 Criteria[4];
};
-#define make_base_tag(ltag, type) struct ltag : public base_tag { using value_type = type; static constexpr char const* tag() { return #ltag; } }
- make_base_tag(area, uint32);
- make_base_tag(areatrigger, uint32);
- make_base_tag(creature, ObjectGuid::LowType);
- make_base_tag(creature_entry, uint32);
- make_base_tag(gameevent, uint32);
- make_base_tag(gameobject, ObjectGuid::LowType);
- make_base_tag(gameobject_entry, uint32);
- make_base_tag(itemset, uint32);
- make_base_tag(player, std::string const&);
- make_base_tag(skill, uint32);
- make_base_tag(taxinode, uint32);
- make_base_tag(tele, uint32);
- make_base_tag(title, uint32);
-#undef make_base_tag
-
- struct TC_GAME_API achievement
+ struct GlyphLinkData
{
- using value_type = AchievementLinkData const&;
- static constexpr char const* tag() { return "achievement"; }
- static bool StoreTo(AchievementLinkData& val, char const* pos, size_t len);
+ GlyphPropertiesEntry const* Glyph;
+ GlyphSlotEntry const* Slot;
};
- struct TC_GAME_API enchant
+ struct ItemLinkData
{
- using value_type = SpellInfo const*;
- static constexpr char const* tag() { return "enchant"; }
- static bool StoreTo(SpellInfo const*& val, char const* pos, size_t len);
+ ItemTemplate const* Item;
+ uint32 EnchantId;
+ uint32 GemEnchantId[3];
+ int32 RandomPropertyId;
+ int32 RandomPropertySeed;
+ uint8 RenderLevel;
};
- struct TC_GAME_API glyph
+ struct QuestLinkData
{
- using value_type = GlyphLinkData const&;
- static constexpr char const* tag() { return "glyph"; };
- static bool StoreTo(GlyphLinkData& val, char const* pos, size_t len);
+ ::Quest const* Quest;
+ uint8 QuestLevel;
};
- struct TC_GAME_API item
+ struct TalentLinkData
{
- using value_type = ItemLinkData const&;
- static constexpr char const* tag() { return "item"; }
- static bool StoreTo(ItemLinkData& val, char const* pos, size_t len);
+ TalentEntry const* Talent;
+ uint8 Rank;
};
- struct TC_GAME_API quest
+ struct TradeskillLinkData
{
- using value_type = QuestLinkData const&;
- static constexpr char const* tag() { return "quest"; }
- static bool StoreTo(QuestLinkData& val, char const* pos, size_t len);
+ SpellInfo const* Spell;
+ uint16 CurValue;
+ uint16 MaxValue;
+ ObjectGuid Owner;
+ std::string KnownRecipes;
};
- struct TC_GAME_API spell
- {
- using value_type = SpellInfo const*;
- static constexpr char const* tag() { return "spell"; }
- static bool StoreTo(SpellInfo const*& val, char const* pos, size_t len);
- };
+ namespace LinkTags {
+
+ /************************** LINK TAGS ***************************************************\
+ |* Link tags must abide by the following: *|
+ |* - MUST expose ::value_type typedef *|
+ |* - storage type is remove_cvref_t<value_type> *|
+ |* - MUST expose static ::tag method, void -> const char* *|
+ |* - this method SHOULD be constexpr *|
+ |* - returns identifier string for the link ("creature", "creature_entry", "item") *|
+ |* - MUST expose static ::StoreTo method, (storage&, char const*, size_t) *|
+ |* - assign value_type& based on content of std::string(char const*, size_t) *|
+ |* - return value indicates success/failure *|
+ |* - for integral/string types this can be achieved by extending base_tag *|
+ \****************************************************************************************/
+ struct base_tag
+ {
+ static bool StoreTo(std::string& val, char const* pos, size_t len)
+ {
+ val.assign(pos, len);
+ return true;
+ }
+
+ template <typename T>
+ static std::enable_if_t<std::is_integral_v<T> && std::is_unsigned_v<T>, bool> StoreTo(T& val, char const* pos, size_t len)
+ {
+ try { val = std::stoull(std::string(pos, len)); }
+ catch (...) { return false; }
+ return true;
+ }
+
+ template <typename T>
+ static std::enable_if_t<std::is_integral_v<T> && std::is_signed_v<T>, bool> StoreTo(T& val, char const* pos, size_t len)
+ {
+ try { val = std::stoll(std::string(pos, len)); }
+ catch (...) { return false; }
+ return true;
+ }
+
+ static bool StoreTo(ObjectGuid& val, char const* pos, size_t len)
+ {
+ try { val.Set(std::stoul(std::string(pos, len), nullptr, 16)); }
+ catch (...) { return false; }
+ return true;
+ }
+ };
+
+ #define make_base_tag(ltag, type) struct ltag : public base_tag { using value_type = type; static constexpr char const* tag() { return #ltag; } }
+ make_base_tag(area, uint32);
+ make_base_tag(areatrigger, uint32);
+ make_base_tag(creature, ObjectGuid::LowType);
+ make_base_tag(creature_entry, uint32);
+ make_base_tag(gameevent, uint32);
+ make_base_tag(gameobject, ObjectGuid::LowType);
+ make_base_tag(gameobject_entry, uint32);
+ make_base_tag(itemset, uint32);
+ make_base_tag(player, std::string const&);
+ make_base_tag(skill, uint32);
+ make_base_tag(taxinode, uint32);
+ make_base_tag(tele, uint32);
+ make_base_tag(title, uint32);
+ #undef make_base_tag
+
+ struct TC_GAME_API achievement
+ {
+ using value_type = AchievementLinkData const&;
+ static constexpr char const* tag() { return "achievement"; }
+ static bool StoreTo(AchievementLinkData& val, char const* pos, size_t len);
+ };
- struct TC_GAME_API talent
- {
- using value_type = TalentLinkData const&;
- static constexpr char const* tag() { return "talent"; }
- static bool StoreTo(TalentLinkData& val, char const* pos, size_t len);
- };
+ struct TC_GAME_API enchant
+ {
+ using value_type = SpellInfo const*;
+ static constexpr char const* tag() { return "enchant"; }
+ static bool StoreTo(SpellInfo const*& val, char const* pos, size_t len);
+ };
+
+ struct TC_GAME_API glyph
+ {
+ using value_type = GlyphLinkData const&;
+ static constexpr char const* tag() { return "glyph"; };
+ static bool StoreTo(GlyphLinkData& val, char const* pos, size_t len);
+ };
+
+ struct TC_GAME_API item
+ {
+ using value_type = ItemLinkData const&;
+ static constexpr char const* tag() { return "item"; }
+ static bool StoreTo(ItemLinkData& val, char const* pos, size_t len);
+ };
+
+ struct TC_GAME_API quest
+ {
+ using value_type = QuestLinkData const&;
+ static constexpr char const* tag() { return "quest"; }
+ static bool StoreTo(QuestLinkData& val, char const* pos, size_t len);
+ };
+
+ struct TC_GAME_API spell
+ {
+ using value_type = SpellInfo const*;
+ static constexpr char const* tag() { return "spell"; }
+ static bool StoreTo(SpellInfo const*& val, char const* pos, size_t len);
+ };
+
+ struct TC_GAME_API talent
+ {
+ using value_type = TalentLinkData const&;
+ static constexpr char const* tag() { return "talent"; }
+ static bool StoreTo(TalentLinkData& val, char const* pos, size_t len);
+ };
- struct TC_GAME_API trade
+ struct TC_GAME_API trade
+ {
+ using value_type = TradeskillLinkData const&;
+ static constexpr char const* tag() { return "trade"; }
+ static bool StoreTo(TradeskillLinkData& val, char const* pos, size_t len);
+ };
+ }
+
+ struct HyperlinkColor
{
- using value_type = TradeskillLinkData const&;
- static constexpr char const* tag() { return "trade"; }
- static bool StoreTo(TradeskillLinkData& val, char const* pos, size_t len);
+ HyperlinkColor(uint32 c) : r(c >> 16), g(c >> 8), b(c), a(c >> 24) {}
+ uint8 r, g, b, a;
+ bool operator==(uint32 c) const
+ {
+ if ((c & 0xff) ^ b)
+ return false;
+ if (((c >>= 8) & 0xff) ^ g)
+ return false;
+ if (((c >>= 8) & 0xff) ^ r)
+ return false;
+ if ((c >>= 8) ^ a)
+ return false;
+ return true;
+ }
};
-}
-struct HyperlinkColor
-{
- HyperlinkColor(uint32 c) : r(c >> 16), g(c >> 8), b(c), a(c >> 24) {}
- uint8 r, g, b, a;
- bool operator==(uint32 c) const
+ struct HyperlinkInfo
{
- if ((c & 0xff) ^ b)
- return false;
- if (((c >>= 8) & 0xff) ^ g)
- return false;
- if (((c >>= 8) & 0xff) ^ r)
- return false;
- if ((c >>= 8) ^ a)
- return false;
- return true;
- }
-};
-
-struct HyperlinkInfo
-{
- HyperlinkInfo(char const* n = nullptr, uint32 c = 0, char const* tS = nullptr, size_t tL = 0, char const* dS = nullptr, size_t dL = 0, char const* cS = nullptr, size_t cL = 0) :
- next(n), color(c), tag(tS, tL), data(dS, dL), text(cS, cL) {}
-
- explicit operator bool() { return next; }
- char const* const next;
- HyperlinkColor const color;
- std::pair<char const*, size_t> const tag;
- std::pair<char const*, size_t> const data;
- std::pair<char const*, size_t> const text;
-};
-HyperlinkInfo TC_GAME_API ParseHyperlink(char const* pos);
-bool TC_GAME_API CheckAllLinks(std::string const&);
+ HyperlinkInfo(char const* n = nullptr, uint32 c = 0, char const* tS = nullptr, size_t tL = 0, char const* dS = nullptr, size_t dL = 0, char const* cS = nullptr, size_t cL = 0) :
+ next(n), color(c), tag(tS, tL), data(dS, dL), text(cS, cL) {}
+
+ explicit operator bool() { return next; }
+ char const* const next;
+ HyperlinkColor const color;
+ std::pair<char const*, size_t> const tag;
+ std::pair<char const*, size_t> const data;
+ std::pair<char const*, size_t> const text;
+ };
+ HyperlinkInfo TC_GAME_API ParseHyperlink(char const* pos);
+ bool TC_GAME_API CheckAllLinks(std::string const&);
}
-}
#endif