better print override
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
namespace sp {
|
namespace sp {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::string GetClassName(const T& a_Value) {
|
std::string GetBasicClassName(const T& a_Value) {
|
||||||
int status;
|
int status;
|
||||||
char* demangled = abi::__cxa_demangle(typeid(a_Value).name(), 0, 0, &status);
|
char* demangled = abi::__cxa_demangle(typeid(a_Value).name(), 0, 0, &status);
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
@@ -15,7 +15,7 @@ std::string GetClassName(const T& a_Value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::string GetClassName() {
|
std::string GetBasicClassName() {
|
||||||
int status;
|
int status;
|
||||||
char* demangled = abi::__cxa_demangle(typeid(T).name(), 0, 0, &status);
|
char* demangled = abi::__cxa_demangle(typeid(T).name(), 0, 0, &status);
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
@@ -23,4 +23,38 @@ std::string GetClassName() {
|
|||||||
return std::string(demangled);
|
return std::string(demangled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct Reflector {
|
||||||
|
static std::string GetClassName() {
|
||||||
|
return GetBasicClassName<T>();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Reflector<std::string> {
|
||||||
|
static std::string GetClassName() {
|
||||||
|
return "std::string";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename K, typename V>
|
||||||
|
struct Reflector<std::map<K, V>> {
|
||||||
|
static std::string GetClassName();
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct Reflector<std::vector<T>> {
|
||||||
|
static std::string GetClassName();
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::string Reflector<std::vector<T>>::GetClassName() {
|
||||||
|
return "std::vector<" + Reflector<T>::GetClassName() + ">";
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename K, typename V>
|
||||||
|
std::string Reflector<std::map<K, V>>::GetClassName() {
|
||||||
|
return "std::map<" + Reflector<K>::GetClassName() + ", " + Reflector<V>::GetClassName() + ">";
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace sp
|
} // namespace sp
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace sp {
|
namespace sp {
|
||||||
|
|
||||||
@@ -50,4 +51,48 @@ void TupleForEach(TFunc&& func, TTuple&& tuple) {
|
|||||||
details::TupleForEachHelper<TupleSize>::Exec(std::forward<TTuple>(tuple), std::forward<TFunc>(func));
|
details::TupleForEachHelper<TupleSize>::Exec(std::forward<TTuple>(tuple), std::forward<TFunc>(func));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace details {
|
||||||
|
|
||||||
|
template <typename T, typename U = void>
|
||||||
|
struct is_mappish_impl : std::false_type {};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_mappish_impl<T, std::void_t<typename T::key_type, typename T::mapped_type,
|
||||||
|
decltype(std::declval<T&>()[std::declval<const typename T::key_type&>()])>> : std::true_type {};
|
||||||
|
|
||||||
|
template <typename T, typename U = void>
|
||||||
|
struct is_vectish_impl : std::false_type {};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_vectish_impl<T,
|
||||||
|
std::void_t<typename T::value_type, decltype(std::declval<T&>()[std::declval<const typename T::value_type&>()])>>
|
||||||
|
: std::true_type {};
|
||||||
|
|
||||||
|
template <typename T, typename U = void>
|
||||||
|
struct is_pairish_impl : std::false_type {};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_pairish_impl<T,
|
||||||
|
std::void_t<typename T::first_type, decltype(std::declval<T&>()[std::declval<const typename T::first_type&>()])>>
|
||||||
|
: std::true_type {};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using is_general_t = std::integral_constant<bool,
|
||||||
|
(std::is_same_v<T, std::string> || (!std::is_same_v<T, char> && !std::is_same_v<T, unsigned char> && !std::is_arithmetic_v<T> &&
|
||||||
|
!is_pairish_impl<T>::value && !is_mappish_impl<T>::value && !is_vectish_impl<T>::value))>;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using is_primitive =
|
||||||
|
std::integral_constant<bool, std::is_same_v<T, char> || std::is_same_v<T, unsigned char> || std::is_arithmetic_v<T>>;
|
||||||
|
|
||||||
|
} // namespace details
|
||||||
|
|
||||||
} // namespace sp
|
} // namespace sp
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <ostream>
|
#include <sp/protocol/MessagePrinter.h>
|
||||||
|
|
||||||
namespace sp {
|
namespace sp {
|
||||||
|
|
||||||
@@ -56,11 +56,11 @@ class VarInt {
|
|||||||
* \param var The variable integer to deserialize
|
* \param var The variable integer to deserialize
|
||||||
*/
|
*/
|
||||||
friend DataBuffer& operator>>(DataBuffer& in, VarInt& var);
|
friend DataBuffer& operator>>(DataBuffer& in, VarInt& var);
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief overriding stream operator
|
|
||||||
*/
|
|
||||||
friend std::ostream& operator<<(std::ostream& a_Stream, const sp::VarInt& a_VarInt);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline std::string PrintData(const VarInt& a_VarInt) {
|
||||||
|
return PrintData(a_VarInt.GetValue());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace sp
|
} // namespace sp
|
||||||
|
|||||||
55
include/sp/protocol/MessagePrinter.h
Normal file
55
include/sp/protocol/MessagePrinter.h
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <sp/common/Templates.h>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace sp {
|
||||||
|
|
||||||
|
template <typename T, std::enable_if_t<details::is_general_t<T>::value, bool> = true>
|
||||||
|
inline std::string PrintData(const T& a_Data);
|
||||||
|
|
||||||
|
template <typename T, std::enable_if_t<details::is_primitive<T>::value, bool> = true>
|
||||||
|
inline std::string PrintData(T a_Data) {
|
||||||
|
return std::to_string(a_Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline std::string PrintData(const std::string& a_Data) {
|
||||||
|
return "\"" + a_Data + "\"";
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename K, typename V>
|
||||||
|
std::string PrintData(const std::pair<K, V>& a_Data);
|
||||||
|
|
||||||
|
template <typename K, typename V>
|
||||||
|
std::string PrintData(const std::map<K, V>& a_Data);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::string PrintData(const std::vector<T>& a_Data);
|
||||||
|
|
||||||
|
template <typename K, typename V>
|
||||||
|
std::string PrintData(const std::pair<K, V>& a_Data) {
|
||||||
|
return "{" + PrintData(a_Data.first) + " => " + PrintData(a_Data.second) + "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename K, typename V>
|
||||||
|
std::string PrintData(const std::map<K, V>& a_Data) {
|
||||||
|
std::string result = "{";
|
||||||
|
for (const auto& pair : a_Data) {
|
||||||
|
result += PrintData(pair) + ", ";
|
||||||
|
}
|
||||||
|
return result.substr(0, result.size() - 2) + "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::string PrintData(const std::vector<T>& a_Data) {
|
||||||
|
std::string result = "{";
|
||||||
|
for (const T& value : a_Data) {
|
||||||
|
result += PrintData(value) + ", ";
|
||||||
|
}
|
||||||
|
return result.substr(0, result.size() - 2) + "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace sp
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <sp/common/Templates.h>
|
|
||||||
#include <sp/common/Reflection.h>
|
#include <sp/common/Reflection.h>
|
||||||
|
#include <sp/common/Templates.h>
|
||||||
|
#include <sp/protocol/MessagePrinter.h>
|
||||||
|
|
||||||
namespace sp {
|
namespace sp {
|
||||||
namespace details {
|
namespace details {
|
||||||
@@ -31,37 +31,20 @@ struct IdPrinter<option::StaticNumIdImpl<TId>, TOptions...> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
std::string PrintData(const T& a_Data) {
|
|
||||||
std::stringstream sStream;
|
|
||||||
sStream << a_Data;
|
|
||||||
return sStream.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
std::string PrintData<char>(const char& a_Data) {
|
|
||||||
return std::to_string(a_Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
std::string PrintData<unsigned char>(const unsigned char& a_Data) {
|
|
||||||
return std::to_string(a_Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... TFields>
|
template <typename... TFields>
|
||||||
std::string PrintFields(const std::tuple<TFields...>& a_Fields);
|
std::string PrintFields(const std::tuple<TFields...>& a_Fields);
|
||||||
|
|
||||||
template <typename TField, unsigned int IAlignment>
|
template <typename TField, unsigned int IAlignment>
|
||||||
struct FieldPrinter {
|
struct FieldPrinter {
|
||||||
static std::string PrintField(const sp::Field<TField, IAlignment>& a_Field) {
|
static std::string PrintField(const sp::Field<TField, IAlignment>& a_Field) {
|
||||||
return GetClassName<TField>() + "=" + PrintData(a_Field.GetValue());
|
return Reflector<TField>::GetClassName() + "=" + PrintData(a_Field.GetValue());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <unsigned int IAlignment, typename TContainer, typename... TFields>
|
template <unsigned int IAlignment, typename TContainer, typename... TFields>
|
||||||
struct FieldPrinter<BitField<TContainer, TFields...>, IAlignment> {
|
struct FieldPrinter<BitField<TContainer, TFields...>, IAlignment> {
|
||||||
static std::string PrintField(const Field<BitField<TContainer, TFields...>, IAlignment>& a_Field) {
|
static std::string PrintField(const Field<BitField<TContainer, TFields...>, IAlignment>& a_Field) {
|
||||||
return "BitField<" + GetClassName<TContainer>() + ">[" + PrintFields(a_Field.GetValue().GetFields()) + "]";
|
return "BitField<" + Reflector<TContainer>::GetClassName() + ">[" + PrintFields(a_Field.GetValue().GetFields()) + "]";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -80,7 +63,7 @@ std::string PrintFields(const std::tuple<TFields...>& a_Fields) {
|
|||||||
|
|
||||||
template <typename TBase, typename... TOptions>
|
template <typename TBase, typename... TOptions>
|
||||||
std::string PrintMessage(const MessageBase<TBase, TOptions...>& a_Message) {
|
std::string PrintMessage(const MessageBase<TBase, TOptions...>& a_Message) {
|
||||||
return sp::GetClassName(a_Message) + sp::details::IdPrinter<TOptions...>::PrintMessageId() + "[" +
|
return sp::GetBasicClassName(a_Message) + sp::details::IdPrinter<TOptions...>::PrintMessageId() + "[" +
|
||||||
sp::details::PrintFields(a_Message.GetFields()) + "]";
|
sp::details::PrintFields(a_Message.GetFields()) + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,9 +49,4 @@ DataBuffer& operator>>(DataBuffer& in, VarInt& var) {
|
|||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& a_Stream, const sp::VarInt& a_VarInt) {
|
|
||||||
a_Stream << a_VarInt.GetValue();
|
|
||||||
return a_Stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace sp
|
} // namespace sp
|
||||||
|
|||||||
Reference in New Issue
Block a user