#ifndef VCZH_REFLECTION_GUITYPEDESCRIPTORMACROS
#define VCZH_REFLECTION_GUITYPEDESCRIPTORMACROS
#include "GuiTypeDescriptorBuilder.h"
#include "GuiTypeDescriptorBuilder_Container.h"
#include "GuiTypeDescriptorBuilder_Function.h"
#include "GuiTypeDescriptorBuilder_Struct.h"
#ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA
namespace
 
{
	
namespace
 
	{
		
namespace
 
		{
			
template
<
typename
 >
			
struct
 CustomTypeDescriptorSelector
{};
			
struct
 
			{
				
typedef
 collections
::
<
, 
*>		
;
				
class
  : 
public
 virtual
 
				{
				
public
:
					
virtual
 void
 (
const
 & 
, 
* 
) = 
0
;
					
virtual
 * 
(
const
 & 
) = 
0
;
				};
				
 [
4
];
				
static
 inline
  (
const
 & 
, 
const
 & 
)
				{
					{
						
auto
  = 
.
[
0
] - 
.
[
0
];
						
if
 (
result
 != 
0
) 
return
 result
;
					}
					{
						
auto
  = 
.
[
1
] - 
.
[
1
];
						
if
 (
result
 != 
0
) 
return
 result
;
					}
					{
						
auto
  = 
.
[
2
] - 
.
[
2
];
						
if
 (
result
 != 
0
) 
return
 result
;
					}
					{
						
auto
  = 
.
[
3
] - 
.
[
3
];
						
if
 (
result
 != 
0
) 
return
 result
;
					}
					
return
 0
;
				}
#define COMPARE(OPERATOR)\
				inline bool operator OPERATOR(const MethodPointerBinaryData& d)const\
				{\
					return Compare(*this, d) OPERATOR 0;\
				}
				COMPARE(<)
				inline
 bool
 (
const
 & 
)
const
 { 
return
 (*
this
, 
) < 
0
; }
 				COMPARE(<=)
				inline
 bool
 (
const
 & 
)
const
 { 
return
 (*
this
, 
) <= 
0
; }
 				COMPARE(>)
				inline
 bool
 (
const
 & 
)
const
 { 
return
 (*
this
, 
) > 
0
; }
 				COMPARE(>=)
				inline
 bool
 (
const
 & 
)
const
 { 
return
 (*
this
, 
) >= 
0
; }
 				COMPARE(==)
				inline
 bool
 (
const
 & 
)
const
 { 
return
 (*
this
, 
) == 
0
; }
 				COMPARE(!=)
				inline
 bool
 (
const
 & 
)
const
 { 
return
 (*
this
, 
) != 
0
; }
 #undef COMPARE
			};
			
template
<
typename
 >
			
union
 MethodPointerBinaryDataRetriver
			{
				
 ;
				
 ;
				
MethodPointerBinaryDataRetriver
(
 )
				{
					
(&
, 
0
, 
sizeof
(
));
					
 = 
;
				}
				
const
 & 
()
				{
					
static_assert
(
sizeof
(
) <= 
sizeof
(
), 
"Your C++ compiler is bad!"
);
					
return
 ;
				}
			};
			
template
<
typename
 , 
 >
			
struct
 MethodPointerBinaryDataRecorder
			{
				
static
 void
 (
const
 & 
, 
* 
, 
* 
)
				{
				}
			};
			
template
<
typename
 >
			
struct
 MethodPointerBinaryDataRecorder
<
, 
::
>
			{
				
static
 void
 (
const
 & 
, 
* 
, 
* 
)
				{
					
auto
  = 
dynamic_cast
<
::
*>(
);
					CHECK_ERROR(impl != nullptr, L"Internal error: RecordMethod can only be called when registering methods.");
					do
{
if
(!(
impl
 != 
nullptr
))
throw
 (
L"Internal error: RecordMethod can only be called when registering methods."
);}
while
(
0
);
 impl
->
(
, 
);
				}
			};
			
template
<
typename
 >
			
using
  = 
*;
#define BEGIN_TYPE_INFO_NAMESPACE namespace vl{namespace reflection{namespace description{
#define END_TYPE_INFO_NAMESPACE }}}
#define ADD_TYPE_INFO(TYPENAME)\
			{\
				Ptr<ITypeDescriptor> type=new CustomTypeDescriptorSelector<TYPENAME>::CustomTypeDescriptorImpl();\
				manager->SetTypeDescriptor(TypeInfo<TYPENAME>::content.typeName, type);\
			}
#define INTERFACE_PROXY_CTOR_RAWPTR(INTERFACE)\
			static INTERFACE* Create(Ptr<IValueInterfaceProxy> proxy)\
			{\
				auto obj = new ValueInterfaceProxy<INTERFACE>();\
				obj->SetProxy(proxy);\
				return obj;\
			}\
#define INTERFACE_PROXY_CTOR_SHAREDPTR(INTERFACE)\
			static Ptr<INTERFACE> Create(Ptr<IValueInterfaceProxy> proxy)\
			{\
				auto obj = new ValueInterfaceProxy<INTERFACE>();\
				obj->SetProxy(proxy);\
				return obj;\
			}\
#define BEGIN_INTERFACE_PROXY_NOPARENT_HEADER(INTERFACE)\
			template<>\
			class ValueInterfaceProxy<INTERFACE> : public ValueInterfaceImpl<INTERFACE>\
			{\
				typedef INTERFACE _interface_proxy_InterfaceType;\
			public:\
#define BEGIN_INTERFACE_PROXY_NOPARENT_RAWPTR(INTERFACE)\
			BEGIN_INTERFACE_PROXY_NOPARENT_HEADER(INTERFACE)\
			INTERFACE_PROXY_CTOR_RAWPTR(INTERFACE)\
#define BEGIN_INTERFACE_PROXY_NOPARENT_SHAREDPTR(INTERFACE)\
			BEGIN_INTERFACE_PROXY_NOPARENT_HEADER(INTERFACE)\
			INTERFACE_PROXY_CTOR_SHAREDPTR(INTERFACE)\
#define BEGIN_INTERFACE_PROXY_HEADER(INTERFACE, ...)\
			template<>\
			class ValueInterfaceProxy<INTERFACE> : public ValueInterfaceImpl<INTERFACE, __VA_ARGS__>\
			{\
				typedef INTERFACE _interface_proxy_InterfaceType;\
			public:\
#define BEGIN_INTERFACE_PROXY_RAWPTR(INTERFACE, ...)\
			BEGIN_INTERFACE_PROXY_HEADER(INTERFACE, __VA_ARGS__)\
			INTERFACE_PROXY_CTOR_RAWPTR(INTERFACE)\
#define BEGIN_INTERFACE_PROXY_SHAREDPTR(INTERFACE, ...)\
			BEGIN_INTERFACE_PROXY_HEADER(INTERFACE, __VA_ARGS__)\
			INTERFACE_PROXY_CTOR_SHAREDPTR(INTERFACE)\
#define END_INTERFACE_PROXY(INTERFACE)\
			};
			template
<
typename
 , 
typename
 , 
typename
 ...
>
			
auto
 (
...)->
(
::*)(
...)
			{
				
return
 nullptr
;
			}
#define PREPARE_INVOKE_INTERFACE_PROXY(METHODNAME, ...)\
			static ITypeDescriptor* _interface_proxy_typeDescriptor = nullptr;\
			static IMethodInfo* _interface_proxy_methodInfo = nullptr;\
			if (_interface_proxy_typeDescriptor != static_cast<DescriptableObject*>(this)->GetTypeDescriptor())\
			{\
				_interface_proxy_typeDescriptor = static_cast<DescriptableObject*>(this)->GetTypeDescriptor();\
				CHECK_ERROR(_interface_proxy_typeDescriptor != nullptr, L"Internal error: The type of this interface has not been registered.");\
				auto impl = dynamic_cast<MethodPointerBinaryData::IIndexer*>(_interface_proxy_typeDescriptor);\
				CHECK_ERROR(impl != nullptr, L"Internal error: BEGIN_INTERFACE_PROXY is the only correct way to register an interface with a proxy.");\
				auto _interface_proxy_method\
					= (decltype(MethodTypeTrait<_interface_proxy_InterfaceType, decltype(METHODNAME(__VA_ARGS__))>(__VA_ARGS__)))\
					&_interface_proxy_InterfaceType::METHODNAME;\
				MethodPointerBinaryDataRetriver<decltype(_interface_proxy_method)> binaryData(_interface_proxy_method);\
				_interface_proxy_methodInfo = impl->GetIndexedMethodInfo(binaryData.GetBinaryData());\
			}\
#define INVOKE_INTERFACE_PROXY(METHODNAME, ...)\
			PREPARE_INVOKE_INTERFACE_PROXY(METHODNAME, __VA_ARGS__)\
			proxy->Invoke(_interface_proxy_methodInfo, IValueList::Create(collections::From((collections::Array<Value>&)(Value_xs(), __VA_ARGS__))))
#define INVOKE_INTERFACE_PROXY_NOPARAMS(METHODNAME)\
			PREPARE_INVOKE_INTERFACE_PROXY(METHODNAME)\
			proxy->Invoke(_interface_proxy_methodInfo, IValueList::Create())
#define INVOKEGET_INTERFACE_PROXY(METHODNAME, ...)\
			PREPARE_INVOKE_INTERFACE_PROXY(METHODNAME, __VA_ARGS__)\
			return UnboxValue<decltype(METHODNAME(__VA_ARGS__))>(proxy->Invoke(_interface_proxy_methodInfo, IValueList::Create(collections::From((collections::Array<Value>&)(Value_xs(), __VA_ARGS__)))))
#define INVOKEGET_INTERFACE_PROXY_NOPARAMS(METHODNAME)\
			PREPARE_INVOKE_INTERFACE_PROXY(METHODNAME)\
			return UnboxValue<decltype(METHODNAME())>(proxy->Invoke(_interface_proxy_methodInfo, IValueList::Create()))
#define BEGIN_ENUM_ITEM_FLAG(TYPENAME, TDFLAGS)\
			template<>\
			struct CustomTypeDescriptorSelector<TYPENAME>\
			{\
			public:\
				class CustomTypeDescriptorImpl : public EnumTypeDescriptor<TYPENAME, TDFLAGS>\
				{\
					typedef TYPENAME EnumType;\
				public:\
					void LoadInternal()override\
					{\
						EnumTypeDescriptor<TYPENAME, TDFLAGS>::LoadInternal();\
#define BEGIN_ENUM_ITEM(TYPENAME) BEGIN_ENUM_ITEM_FLAG(TYPENAME, TypeDescriptorFlags::NormalEnum)
#define BEGIN_ENUM_ITEM_MERGABLE(TYPENAME) BEGIN_ENUM_ITEM_FLAG(TYPENAME, TypeDescriptorFlags::FlagEnum)
#define END_ENUM_ITEM(TYPENAME)\
					}\
				};\
			};
#define ENUM_ITEM_NAMESPACE(TYPENAME) typedef TYPENAME EnumItemNamespace;
#define ENUM_ITEM(ITEMNAME) enumType->AddItem(L ## #ITEMNAME, ITEMNAME);
#define ENUM_NAMESPACE_ITEM(ITEMNAME) enumType->AddItem(L ## #ITEMNAME, EnumItemNamespace::ITEMNAME);
#define ENUM_CLASS_ITEM(ITEMNAME) enumType->AddItem(L ## #ITEMNAME, EnumType::ITEMNAME);
#define BEGIN_STRUCT_MEMBER_FLAG(TYPENAME, TDFLAGS)\
			template<>\
			struct CustomTypeDescriptorSelector<TYPENAME>\
			{\
			public:\
				class CustomTypeDescriptorImpl : public StructTypeDescriptor<TYPENAME, TDFLAGS>\
				{\
					typedef TYPENAME StructType;\
				protected:\
					void LoadInternal()override\
					{
#define BEGIN_STRUCT_MEMBER(TYPENAME)\
			BEGIN_STRUCT_MEMBER_FLAG(TYPENAME, TypeDescriptorFlags::Struct)
#define END_STRUCT_MEMBER(TYPENAME)\
					}\
				};\
			};
#define STRUCT_MEMBER(FIELDNAME)\
	fields.Add(L ## #FIELDNAME, new StructFieldInfo<decltype(((StructType*)0)->FIELDNAME)>(this, &StructType::FIELDNAME, L ## #FIELDNAME));
#define BEGIN_CLASS_MEMBER(TYPENAME)\
			template<>\
			struct CustomTypeDescriptorSelector<TYPENAME>\
			{\
			public:\
				class CustomTypeDescriptorImpl : public TypeDescriptorImpl\
				{\
					typedef TYPENAME ClassType;\
					static const TypeDescriptorFlags		TDFlags = TypeDescriptorFlags::Class;\
				public:\
					CustomTypeDescriptorImpl()\
						:TypeDescriptorImpl(TDFlags, &TypeInfo<TYPENAME>::content)\
					{\
						Description<TYPENAME>::SetAssociatedTypeDescriptor(this);\
					}\
					~CustomTypeDescriptorImpl()\
					{\
						Description<TYPENAME>::SetAssociatedTypeDescriptor(0);\
					}\
				protected:\
					bool IsAggregatable()override\
					{\
						return AcceptValue<typename PointerConvertable<TYPENAME, AggregatableDescription<TYPENAME>>::YesNoType>::Result;\
					}\
					void LoadInternal()override\
					{
#define CLASS_MEMBER_BASE(TYPENAME)\
			AddBaseType(description::GetTypeDescriptor<TYPENAME>());
#define END_CLASS_MEMBER(TYPENAME)\
						if (GetBaseTypeDescriptorCount() == 0) CLASS_MEMBER_BASE(DescriptableObject)\
					}\
				};\
			};
#define BEGIN_INTERFACE_MEMBER_NOPROXY_FLAG(TYPENAME, TDFLAGS)\
			template<>\
			struct CustomTypeDescriptorSelector<TYPENAME>\
			{\
			public:\
				class CustomTypeDescriptorImpl : public TypeDescriptorImpl, public MethodPointerBinaryData::IIndexer\
				{\
					typedef TYPENAME						ClassType;\
					static const TypeDescriptorFlags		TDFlags = TDFLAGS;\
					MethodPointerBinaryData::MethodMap		methodsForProxy;\
				public:\
					CustomTypeDescriptorImpl()\
						:TypeDescriptorImpl(TDFLAGS, &TypeInfo<TYPENAME>::content)\
					{\
						Description<TYPENAME>::SetAssociatedTypeDescriptor(this);\
					}\
					~CustomTypeDescriptorImpl()\
					{\
						Description<TYPENAME>::SetAssociatedTypeDescriptor(0);\
					}\
					void IndexMethodInfo(const MethodPointerBinaryData& data, IMethodInfo* methodInfo)override\
					{\
						methodsForProxy.Add(data, methodInfo);\
					}\
					IMethodInfo* GetIndexedMethodInfo(const MethodPointerBinaryData& data)override\
					{\
						Load();\
						return methodsForProxy[data];\
					}\
				protected:\
					void LoadInternal()override\
					{
#define BEGIN_INTERFACE_MEMBER_NOPROXY(TYPENAME)\
			BEGIN_INTERFACE_MEMBER_NOPROXY_FLAG(TYPENAME, TypeDescriptorFlags::Interface)
#define BEGIN_INTERFACE_MEMBER(TYPENAME)\
	BEGIN_INTERFACE_MEMBER_NOPROXY(TYPENAME)\
	CLASS_MEMBER_EXTERNALCTOR(decltype(ValueInterfaceProxy<TYPENAME>::Create(nullptr))(Ptr<IValueInterfaceProxy>), { L"proxy" }, vl::reflection::description::ValueInterfaceProxy<TYPENAME>::Create)
#define END_INTERFACE_MEMBER(TYPENAME)\
						if (GetBaseTypeDescriptorCount() == 0 && TDFlags == TypeDescriptorFlags::Interface) CLASS_MEMBER_BASE(IDescriptable)\
					}\
				};\
			};
#define CLASS_MEMBER_FIELD(FIELDNAME)\
			AddProperty(\
				new CustomFieldInfoImpl<\
					ClassType,\
					decltype(((ClassType*)0)->FIELDNAME)\
					>(this, L ## #FIELDNAME, &ClassType::FIELDNAME)\
				);
#define NO_PARAMETER {L""}
#define PROTECT_PARAMETERS(...) __VA_ARGS__
#define CLASS_MEMBER_CONSTRUCTOR(FUNCTIONTYPE, PARAMETERNAMES)\
			{\
				const wchar_t* parameterNames[]=PARAMETERNAMES;\
				AddConstructor(new CustomConstructorInfoImpl<FUNCTIONTYPE>(parameterNames));\
			}
#define CLASS_MEMBER_EXTERNALCTOR_TEMPLATE(FUNCTIONTYPE, PARAMETERNAMES, SOURCE, INVOKETEMPLATE, CLOSURETEMPLATE)\
			{\
				const wchar_t* parameterNames[]=PARAMETERNAMES;\
				AddConstructor(\
					new CustomStaticMethodInfoImpl<FUNCTIONTYPE>(parameterNames, SOURCE, INVOKETEMPLATE, CLOSURETEMPLATE)\
					);\
			}
#define CLASS_MEMBER_EXTERNALCTOR(FUNCTIONTYPE, PARAMETERNAMES, SOURCE)\
			CLASS_MEMBER_EXTERNALCTOR_TEMPLATE(FUNCTIONTYPE, PROTECT_PARAMETERS(PARAMETERNAMES), (FUNCTIONNAME_AddPointer<FUNCTIONTYPE>)&::SOURCE, L"::" L ## #SOURCE L"($Arguments)", L"::vl::Func<$Func>(&::" L ## #SOURCE L")")
#define CLASS_MEMBER_EXTERNALMETHOD_TEMPLATE(FUNCTIONNAME, PARAMETERNAMES, FUNCTIONTYPE, SOURCE, INVOKETEMPLATE, CLOSURETEMPLATE)\
			{\
				const wchar_t* parameterNames[]=PARAMETERNAMES;\
				AddMethod(\
					L ## #FUNCTIONNAME,\
					new CustomExternalMethodInfoImpl<\
						ClassType,\
						vl::function_lambda::LambdaRetriveType<FUNCTIONTYPE>::FunctionType\
						>(parameterNames, SOURCE, INVOKETEMPLATE, CLOSURETEMPLATE)\
					);\
			}
#define CLASS_MEMBER_EXTERNALMETHOD(FUNCTIONNAME, PARAMETERNAMES, FUNCTIONTYPE, SOURCE)\
			CLASS_MEMBER_EXTERNALMETHOD_TEMPLATE(FUNCTIONNAME, PROTECT_PARAMETERS(PARAMETERNAMES), FUNCTIONTYPE, &::SOURCE, L"::" L ## #SOURCE L"($This, $Arguments)", L"::vl::Func<$Func>($This, &::" L ## #SOURCE L")")
#define CLASS_MEMBER_METHOD_OVERLOAD_RENAME_TEMPLATE(EXPECTEDNAME, FUNCTIONNAME, PARAMETERNAMES, FUNCTIONTYPE, INVOKETEMPLATE, CLOSURETEMPLATE)\
			{\
				const wchar_t* parameterNames[]=PARAMETERNAMES;\
				auto methodInfo = new CustomMethodInfoImpl<\
						ClassType,\
						vl::function_lambda::LambdaRetriveType<FUNCTIONTYPE>::FunctionType\
						>\
					(parameterNames, (FUNCTIONTYPE)&ClassType::FUNCTIONNAME, INVOKETEMPLATE, CLOSURETEMPLATE);\
				AddMethod(\
					L ## #EXPECTEDNAME,\
					methodInfo\
					);\
				MethodPointerBinaryDataRetriver<FUNCTIONTYPE> binaryDataRetriver(&ClassType::FUNCTIONNAME);\
				MethodPointerBinaryDataRecorder<ClassType, TDFlags>::RecordMethod(binaryDataRetriver.GetBinaryData(), this, methodInfo);\
			}
#define CLASS_MEMBER_METHOD_OVERLOAD_RENAME(EXPECTEDNAME, FUNCTIONNAME, PARAMETERNAMES, FUNCTIONTYPE)\
			CLASS_MEMBER_METHOD_OVERLOAD_RENAME_TEMPLATE(EXPECTEDNAME, FUNCTIONNAME, PROTECT_PARAMETERS(PARAMETERNAMES), FUNCTIONTYPE, L"$This->" L ## #FUNCTIONNAME L"($Arguments)", L"::vl::Func<$Func>($This, &$Type::" L ## #FUNCTIONNAME L")")
#define CLASS_MEMBER_METHOD_OVERLOAD(FUNCTIONNAME, PARAMETERNAMES, FUNCTIONTYPE)\
			CLASS_MEMBER_METHOD_OVERLOAD_RENAME_TEMPLATE(FUNCTIONNAME, FUNCTIONNAME, PROTECT_PARAMETERS(PARAMETERNAMES), FUNCTIONTYPE, nullptr, nullptr)
#define CLASS_MEMBER_METHOD_RENAME(EXPECTEDNAME, FUNCTIONNAME, PARAMETERNAMES)\
			CLASS_MEMBER_METHOD_OVERLOAD_RENAME(EXPECTEDNAME, FUNCTIONNAME, PROTECT_PARAMETERS(PARAMETERNAMES), decltype(&ClassType::FUNCTIONNAME))
#define CLASS_MEMBER_METHOD(FUNCTIONNAME, PARAMETERNAMES)\
			CLASS_MEMBER_METHOD_OVERLOAD(FUNCTIONNAME, PROTECT_PARAMETERS(PARAMETERNAMES), decltype(&ClassType::FUNCTIONNAME))
#define CLASS_MEMBER_STATIC_EXTERNALMETHOD_TEMPLATE(FUNCTIONNAME, PARAMETERNAMES, FUNCTIONTYPE, SOURCE, INVOKETEMPLATE, CLOSURETEMPLATE)\
			{\
				const wchar_t* parameterNames[]=PARAMETERNAMES;\
				AddMethod(\
					L ## #FUNCTIONNAME,\
					new CustomStaticMethodInfoImpl<\
						vl::function_lambda::FunctionObjectRetriveType<FUNCTIONTYPE>::FunctionType\
						>(parameterNames, (FUNCTIONTYPE)SOURCE, INVOKETEMPLATE, CLOSURETEMPLATE)\
					);\
			}
#define CLASS_MEMBER_STATIC_EXTERNALMETHOD(FUNCTIONNAME, PARAMETERNAMES, FUNCTIONTYPE, SOURCE)\
			CLASS_MEMBER_STATIC_EXTERNALMETHOD_TEMPLATE(FUNCTIONNAME, PROTECT_PARAMETERS(PARAMETERNAMES), FUNCTIONTYPE, &::SOURCE, L"::" L ## #SOURCE L"($Arguments)", L"::vl::Func<$Func>(&::" L ## #SOURCE L")")
#define CLASS_MEMBER_STATIC_METHOD_OVERLOAD(FUNCTIONNAME, PARAMETERNAMES, FUNCTIONTYPE)\
			CLASS_MEMBER_STATIC_EXTERNALMETHOD_TEMPLATE(FUNCTIONNAME, PROTECT_PARAMETERS(PARAMETERNAMES), FUNCTIONTYPE, &ClassType::FUNCTIONNAME, nullptr, nullptr)
#define CLASS_MEMBER_STATIC_METHOD(FUNCTIONNAME, PARAMETERNAMES)\
			CLASS_MEMBER_STATIC_METHOD_OVERLOAD(FUNCTIONNAME, PROTECT_PARAMETERS(PARAMETERNAMES), decltype(&ClassType::FUNCTIONNAME))
#define CLASS_MEMBER_EVENT(EVENTNAME)\
			AddEvent(\
				new CustomEventInfoImpl<\
					ClassType,\
					CustomEventFunctionTypeRetriver<decltype(&ClassType::EVENTNAME)>::Type\
					>(this, L ## #EVENTNAME, &ClassType::EVENTNAME)\
				);
#define CLASS_MEMBER_PROPERTY_READONLY(PROPERTYNAME, GETTER)\
			AddProperty(\
				new PropertyInfoImpl(\
					this,\
					L ## #PROPERTYNAME,\
					dynamic_cast<MethodInfoImpl*>(GetMethodGroupByName(L ## #GETTER, true)->GetMethod(0)),\
					nullptr,\
					nullptr\
					)\
				);
#define CLASS_MEMBER_PROPERTY(PROPERTYNAME, GETTER, SETTER)\
			AddProperty(\
				new PropertyInfoImpl(\
					this,\
					L ## #PROPERTYNAME,\
					dynamic_cast<MethodInfoImpl*>(GetMethodGroupByName(L ## #GETTER, true)->GetMethod(0)),\
					dynamic_cast<MethodInfoImpl*>(GetMethodGroupByName(L ## #SETTER, true)->GetMethod(0)),\
					nullptr\
					)\
				);
#define CLASS_MEMBER_PROPERTY_EVENT(PROPERTYNAME, GETTER, SETTER, EVENT)\
			AddProperty(\
				new PropertyInfoImpl(\
					this,\
					L ## #PROPERTYNAME,\
					dynamic_cast<MethodInfoImpl*>(GetMethodGroupByName(L ## #GETTER, true)->GetMethod(0)),\
					dynamic_cast<MethodInfoImpl*>(GetMethodGroupByName(L ## #SETTER, true)->GetMethod(0)),\
					dynamic_cast<EventInfoImpl*>(GetEventByName(L ## #EVENT, true))\
					)\
				);
#define CLASS_MEMBER_PROPERTY_EVENT_READONLY(PROPERTYNAME, GETTER, EVENT)\
			AddProperty(\
				new PropertyInfoImpl(\
					this,\
					L ## #PROPERTYNAME,\
					dynamic_cast<MethodInfoImpl*>(GetMethodGroupByName(L ## #GETTER, true)->GetMethod(0)),\
					nullptr,\
					dynamic_cast<EventInfoImpl*>(GetEventByName(L ## #EVENT, true))\
					)\
				);
#define CLASS_MEMBER_PROPERTY_REFERENCETEMPLATE(PROPERTYNAME, GETTER, SETTER, REFERENCETEMPLATE)\
			AddProperty(\
				new PropertyInfoImpl_StaticCpp(\
					this,\
					L ## #PROPERTYNAME,\
					dynamic_cast<MethodInfoImpl*>(GetMethodGroupByName(L ## #GETTER, true)->GetMethod(0)),\
					dynamic_cast<MethodInfoImpl*>(GetMethodGroupByName(L ## #SETTER, true)->GetMethod(0)),\
					nullptr,\
					WString(REFERENCETEMPLATE, false)\
					)\
				);
#define CLASS_MEMBER_PROPERTY_READONLY_FAST(PROPERTYNAME)\
			CLASS_MEMBER_METHOD(Get##PROPERTYNAME, NO_PARAMETER)\
			CLASS_MEMBER_PROPERTY_READONLY(PROPERTYNAME, Get##PROPERTYNAME)\
#define CLASS_MEMBER_PROPERTY_FAST(PROPERTYNAME)\
			CLASS_MEMBER_METHOD(Get##PROPERTYNAME, NO_PARAMETER)\
			CLASS_MEMBER_METHOD(Set##PROPERTYNAME, {L"value"})\
			CLASS_MEMBER_PROPERTY(PROPERTYNAME, Get##PROPERTYNAME, Set##PROPERTYNAME)\
#define CLASS_MEMBER_PROPERTY_EVENT_FAST(PROPERTYNAME, EVENTNAME)\
			CLASS_MEMBER_METHOD(Get##PROPERTYNAME, NO_PARAMETER)\
			CLASS_MEMBER_METHOD(Set##PROPERTYNAME, {L"value"})\
			CLASS_MEMBER_PROPERTY_EVENT(PROPERTYNAME, Get##PROPERTYNAME, Set##PROPERTYNAME, EVENTNAME)\
#define CLASS_MEMBER_PROPERTY_EVENT_READONLY_FAST(PROPERTYNAME, EVENTNAME)\
			CLASS_MEMBER_METHOD(Get##PROPERTYNAME, NO_PARAMETER)\
			CLASS_MEMBER_PROPERTY_EVENT_READONLY(PROPERTYNAME, Get##PROPERTYNAME, EVENTNAME)\
		}
	}
}
#endif
#endif