Prechádzať zdrojové kódy

添加可选的默认构造器

akemimadoka 7 rokov pred
rodič
commit
ab312eb146
5 zmenil súbory, kde vykonal 92 pridanie a 5 odobranie
  1. 1 1
      Extern/NatsuLib
  2. 33 0
      YumeBot/Jce.cpp
  3. 4 4
      YumeBot/Jce.h
  4. 18 0
      YumeBot/JceStructDef.h
  5. 36 0
      YumeBot/Utility.h

+ 1 - 1
Extern/NatsuLib

@@ -1 +1 @@
-Subproject commit e586491f638561bd219cf6530e127b3678cde905
+Subproject commit e7d7021b5cae3bec13a725fa1d51efdac4ba4e46

+ 33 - 0
YumeBot/Jce.cpp

@@ -508,6 +508,39 @@ void JceOutputStream::doWrite(std::uint32_t tag, std::vector<std::uint8_t> const
 	m_Writer->GetUnderlyingStream()->WriteBytes(reinterpret_cast<ncData>(value.data()), size);
 }
 
+namespace
+{
+	template <template <typename> class Trait, typename T, typename Tuple>
+	constexpr void ReinitializeIf(T& obj, Tuple&& args)
+		noexcept((!Trait<T>::value && !std::tuple_size_v<std::remove_reference_t<Tuple>>) || (std::is_nothrow_destructible_v<T> &&
+																							  noexcept(Utility::InitializeWithTuple(obj, std::forward<Tuple>(args)))))
+	{
+		if constexpr (Trait<T>::value || std::tuple_size_v<std::remove_reference_t<Tuple>>)
+		{
+			obj.T::~T();
+			Utility::InitializeWithTuple(obj, std::forward<Tuple>(args));
+		}
+	}
+}
+
+#define JCE_STRUCT(name, alias) \
+	name::name()\
+	{
+
+#define NO_OP Detail::None
+
+#define DEFAULT_INITIALIZER(...) std::tuple(__VA_ARGS__)
+
+#define FIELD(name, tag, type, ...) \
+		::ReinitializeIf<Utility::ConcatTrait<std::is_class, std::negation>::Result>(m_##name, Utility::ReturnFirst<Utility::ConcatTrait<\
+						Utility::ConcatTrait<Utility::RemoveCvRef, Utility::BindTrait<std::is_same,\
+						Detail::NoneType>::Result>::Result, std::negation>::Result, std::tuple<>>(__VA_ARGS__));
+
+#define END_JCE_STRUCT(name) \
+	}
+
+#include "JceStructDef.h"
+
 #define JCE_STRUCT(name, alias) \
 	name::~name()\
 	{\

+ 4 - 4
YumeBot/Jce.h

@@ -393,12 +393,12 @@ namespace YumeBot::Jce
 		};
 	};
 
-	template <JceStruct::TypeEnum Type, typename AttributeSet>
+	template <JceStruct::TypeEnum Type, typename... Attributes>
 	struct FieldTypeBuilder;
 
 #define FIELD_TYPE_BUILDER_OP(name, code, type) \
 	template <typename... Attributes>\
-	struct FieldTypeBuilder<JceStruct::TypeEnum::name, std::tuple<Attributes...>>\
+	struct FieldTypeBuilder<JceStruct::TypeEnum::name, Attributes...>\
 		: decltype(Utility::RecursiveApply<type, Attributes...>())\
 	{\
 	};
@@ -415,7 +415,7 @@ namespace YumeBot::Jce
 
 #define FIELD(name, tag, type, ...) \
 	private:\
-		typename FieldTypeBuilder<JceStruct::TypeEnum::type, std::tuple<__VA_ARGS__>>::Type m_##name;\
+		typename FieldTypeBuilder<JceStruct::TypeEnum::type, __VA_ARGS__>::Type m_##name;\
 		\
 	public:\
 		const auto& Get##name() const noexcept\
@@ -444,6 +444,7 @@ namespace YumeBot::Jce
 		: public NatsuLib::natRefObjImpl<name, JceStruct>\
 	{\
 	public:\
+		name();\
 		~name();\
 		\
 		nStrView GetJceStructName() const noexcept override;
@@ -453,7 +454,6 @@ namespace YumeBot::Jce
 
 #include "JceStructDef.h"
 
-
 #define NO_OP Detail::None
 
 #define IS_OPTIONAL(defaultValue) defaultValue

+ 18 - 0
YumeBot/JceStructDef.h

@@ -14,6 +14,10 @@
 #define NO_OP
 #endif
 
+#ifndef DEFAULT_INITIALIZER
+#define DEFAULT_INITIALIZER(...) NO_OP
+#endif
+
 #ifndef IS_OPTIONAL
 #define IS_OPTIONAL(defaultValue) NO_OP
 #endif
@@ -89,6 +93,19 @@ JCE_STRUCT(SignatureReq, "KQQConfig.SignatureReq")
 	LONG(uin, 0)
 END_JCE_STRUCT(SignatureReq)
 
+JCE_STRUCT_DEFAULT_ALIAS(RequestPacket)
+	SHORT(iVersion, 1)
+	BYTE(cPacketType, 2, DEFAULT_INITIALIZER(2))
+	INT(iMessageType, 3)
+	INT(iRequestId, 4)
+	STRING1(sServantName, 5)
+	STRING1(sFuncName, 6)
+	SIMPLE_LIST(sBuffer, 7)
+	INT(iTimeout, 8)
+	MAP(context, 9, TEMPLATE_ARGUMENT(nString, nString))
+	MAP(status, 10, TEMPLATE_ARGUMENT(nString, nString))
+END_JCE_STRUCT(RequestPacket)
+
 #undef SIMPLE_LIST
 #undef ZERO_TAG
 #undef STRUCT
@@ -108,6 +125,7 @@ END_JCE_STRUCT(SignatureReq)
 
 #undef TEMPLATE_ARGUMENT
 #undef IS_OPTIONAL
+#undef DEFAULT_INITIALIZER
 #undef NO_OP
 #undef ATTRIBUTE_SET
 

+ 36 - 0
YumeBot/Utility.h

@@ -190,4 +190,40 @@ namespace YumeBot::Utility
 			return value >= static_cast<UType>(std::numeric_limits<TType>::min()) && value <= static_cast<UType>(std::numeric_limits<TType>::max());
 		}
 	}
+
+	template <template <typename> class Trait>
+	constexpr auto Filter() noexcept
+	{
+		return std::tuple();
+	}
+
+	template <template <typename> class Trait, typename Arg, typename... Args>
+	constexpr auto Filter(Arg&& arg, Args&&... args) noexcept
+	{
+		if constexpr (Trait<Arg>::value)
+		{
+			return std::tuple_cat(std::forward_as_tuple<Arg>(arg), Filter<Trait>(std::forward<Args>(args)...));
+		}
+		else
+		{
+			return Filter<Trait>(std::forward<Args>(args)...);
+		}
+	}
+
+	namespace Detail
+	{
+		template <typename T, typename Tuple, std::size_t... Indexes>
+		constexpr void InitializeWithTuple(T& obj, Tuple&& args, std::index_sequence<Indexes...>)
+			noexcept(std::is_nothrow_constructible_v<T, std::tuple_element_t<Indexes, std::remove_reference_t<Tuple>>...>)
+		{
+			new (static_cast<void*>(std::addressof(obj))) T(std::get<Indexes>(std::forward<Tuple>(args))...);
+		}
+	}
+
+	template <typename T, typename Tuple>
+	constexpr void InitializeWithTuple(T& obj, Tuple&& args)
+		noexcept(noexcept(Detail::InitializeWithTuple(obj, std::forward<Tuple>(args), std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<Tuple>>>())))
+	{
+		Detail::InitializeWithTuple(obj, std::forward<Tuple>(args), std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<Tuple>>>());
+	}
 }