aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Chat/ChatCommands
diff options
context:
space:
mode:
authorTreeston <treeston.mmoc@gmail.com>2020-08-17 01:05:09 +0200
committerTreeston <treeston.mmoc@gmail.com>2020-08-17 01:05:09 +0200
commit7bceff1b2aa463f8e28277cc8c6eb2eda1952bb4 (patch)
treea61f3f958ac6703641c84b9cdacd2e6ec1852077 /src/server/game/Chat/ChatCommands
parent1aeb7a09804c81adf759cc8fe7a1b8664a19b7a7 (diff)
revert 1aeb7a0 and f9e7dbd until I can work around GCC being silly
Diffstat (limited to 'src/server/game/Chat/ChatCommands')
-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.h234
4 files changed, 173 insertions, 174 deletions
diff --git a/src/server/game/Chat/ChatCommands/ChatCommandArgs.cpp b/src/server/game/Chat/ChatCommands/ChatCommandArgs.cpp
index fb94f6811b3..62ed5afc6c2 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 = val.visit(AchievementVisitor());
+ data = boost::apply_visitor(AchievementVisitor(), val);
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 = val.visit(GameTeleVisitor());
+ data = boost::apply_visitor(GameTeleVisitor(), val);
return args;
}
@@ -61,22 +61,21 @@ char const* Trinity::ChatCommands::ArgInfo<SpellInfo const*>::TryConsume(SpellIn
{
Variant<Hyperlink<spell>, uint32> val;
if ((args = CommandArgsConsumerSingle<decltype(val)>::TryConsumeTo(val, args)))
- data = val.visit(SpellInfoVisitor());
+ data = boost::apply_visitor(SpellInfoVisitor(), val);
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)
{
- 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;
- }
+ Variant<uint32, ExactSequence<'o', 'n'>, ExactSequence<'o', 'f', 'f'>> val;
+ if ((args = CommandArgsConsumerSingle<decltype(val)>::TryConsumeTo(val, args)))
+ data = boost::apply_visitor(BoolVisitor(), val);
return args;
}
diff --git a/src/server/game/Chat/ChatCommands/ChatCommandArgs.h b/src/server/game/Chat/ChatCommands/ChatCommandArgs.h
index d7fa5cf65db..c9e0723fbf8 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, Trinity::Impl::ChatCommands::tokenize(next));
+ std::string token(args, 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, Trinity::Impl::ChatCommands::tokenize(next));
+ std::string token(args, 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, Trinity::Impl::ChatCommands::tokenize(next));
+ std::string token(args, 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 = Trinity::Impl::ChatCommands::tokenize(next))
+ if (size_t len = 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 e22823e5d35..ff9b5a3b8fc 100644
--- a/src/server/game/Chat/ChatCommands/ChatCommandHelpers.h
+++ b/src/server/game/Chat/ChatCommands/ChatCommandHelpers.h
@@ -20,50 +20,58 @@
#include <type_traits>
-namespace Trinity::ChatCommands
+namespace Trinity
+{
+namespace ChatCommands
{
- static constexpr char COMMAND_DELIMITER = ' ';
- template <typename T, typename = void>
- struct tag_base
- {
- using type = T;
- };
+static constexpr char COMMAND_DELIMITER = ' ';
- template <typename T>
- using tag_base_t = typename tag_base<T>::type;
+/***************** 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;
}
-namespace Trinity::Impl::ChatCommands
+template <typename T, typename = void>
+struct tag_base
{
- /***************** 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;
- }
+ using type = T;
+};
- template <typename T, typename... Ts>
- struct are_all_assignable
- {
- static constexpr bool value = (std::is_assignable_v<T&, Ts> && ...);
- };
+template <typename T>
+using tag_base_t = typename tag_base<T>::type;
- template <std::size_t index, typename T1, typename... Ts>
- struct get_nth : get_nth<index-1, 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 <typename T1, typename... Ts>
- struct get_nth<0, T1, Ts...>
- {
- using type = T1;
- };
+template <std::size_t index, typename T1, typename... Ts>
+struct get_nth : get_nth<index-1, Ts...> { };
- template <std::size_t index, typename... Ts>
- using get_nth_t = typename get_nth<index, Ts...>::type;
+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;
+
+}
}
#endif
diff --git a/src/server/game/Chat/ChatCommands/ChatCommandTags.h b/src/server/game/Chat/ChatCommands/ChatCommandTags.h
index 3451b98a098..feffc25aa25 100644
--- a/src/server/game/Chat/ChatCommands/ChatCommandTags.h
+++ b/src/server/game/Chat/ChatCommands/ChatCommandTags.h
@@ -22,158 +22,150 @@
#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::ChatCommands
+namespace Trinity
{
- /************************** 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>>>
+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)
{
- using type = typename T::value_type;
- };
+ if (*(pos++) == c1)
+ return ExactSequence<chars...>::_TryConsume(pos);
+ else
+ return nullptr;
+ }
- template <char c1, char... chars>
- struct ExactSequence : public ContainerTag
+ template <bool C = isSingleChar>
+ static typename std::enable_if_t<C, char const*> _TryConsume(char const* pos)
{
- using value_type = void;
+ 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;
+ }
- static char const* _TryConsume(char const* 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; }
+
+ char const* TryConsume(char const* pos)
{
- 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
+ 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;
+ tokenize(pos);
+
+ // return final pos
+ return pos;
}
- char const* TryConsume(char const* pos) const { return ExactSequence::_TryConsume(pos); }
- };
+ private:
+ storage_type val;
+};
- 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;
-}
+// pull in link tags for user convenience
+using namespace ::Trinity::Hyperlinks::LinkTags;
/************************** VARIANT TAG LOGIC *********************************\
|* This has some special handling over in ChatCommand.h *|
\******************************************************************************/
-namespace Trinity::Impl
-{
- template <typename T>
- struct CastToVisitor {
- template <typename U>
- T operator()(U const& v) const { return v; }
- };
-}
+template <typename T>
+struct CastToVisitor {
+ using result_type = T;
+
+ template <typename U>
+ T operator()(U const& v) const { return v; }
+};
-namespace Trinity::ChatCommands
+template <typename T1, typename... Ts>
+struct Variant : public boost::variant<T1, Ts...>
{
- template <typename T1, typename... Ts>
- struct Variant : public std::variant<T1, Ts...>
- {
- 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;
+ using first_type = tag_base_t<T1>;
+ static constexpr bool have_operators = are_all_assignable<first_type, tag_base_t<Ts>...>::value;
- template <bool C = have_operators>
- std::enable_if_t<C, first_type> operator*() const
- {
- return visit(Trinity::Impl::CastToVisitor<first_type>());
- }
+ template <bool C = have_operators>
+ operator std::enable_if_t<C, first_type>()
+ {
+ return operator*();
+ }
- template <bool C = have_operators>
- operator std::enable_if_t<C, first_type>() const
- {
- return operator*();
- }
+ template <bool C = have_operators>
+ std::enable_if_t<C, first_type> operator*()
+ {
+ return boost::apply_visitor(CastToVisitor<first_type>(), *this);
+ }
- template <typename T>
- Variant& operator=(T&& arg) { std::variant<T1, Ts...>::operator=(std::forward<T>(arg)); return *this; }
+ 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 <size_t index>
- constexpr decltype(auto) get() { return std::get<index>(*this); }
- template <size_t index>
- constexpr decltype(auto) get() const { return std::get<index>(*this); }
+ template <typename T>
+ Variant& operator=(T&& arg) { boost::variant<T1, Ts...>::operator=(std::forward<T>(arg)); return *this; }
- template <typename T>
- constexpr decltype(auto) visit(T&& arg) const { return std::visit(std::forward<T>(arg), *this); }
+ template <size_t index>
+ decltype(auto) get() const { return boost::get<get_nth_t<index, T1, Ts...>>(*this); }
+};
- template <typename T>
- constexpr bool holds_alternative() const { return std::holds_alternative<T>(*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