I thought I'd post the output of the remap compiler in it's simple 'assembler'. There as two 'registers' N and M that point to the offset to copy between, with N offsetting the source, and M offsetting the destination. The two columns on the left of the code sequence below are the values in N and M. I've ordered the operations such that the destination offsets are in order meaning that its often only the source offset that needs to be modified. All instructions will modify the N and M registers such that they are pointing to the following element reducing again the need for N and M skip instructions.
The 'REMAPPER' instruction means run a custom remapper, which can do specialized conversions. Here it's used for copying smart pointers, and enum remapping which the values/flags change. 'CONVERTER' runs a conversion between types - for example converting a UInt8 to UInt16.
Somewhat confusingly non skip instructions ending in '_N' mean that they are to be repeated multiple times.
The instruction stream was produced on x86/mscv - depending on C++ compiler and processor a different instruction stream may be produced, because of word size, alignment, and class layout rules.
0 0 - SKIP_SRC 104 104 0 - REMAPPER TypeCopyRemapper TObjPtr<String> 108 4 - SKIP_SRC -16 92 4 - REMAPPER EnumRemapper@0x093004d0 93 6 - SKIP_SRC -29 64 6 - CONVERT INT32 UINT8 68 7 - SKIP_SRC_DST -56 1 12 8 - CONVERT_N FLOAT32 FLOAT64 [3] 24 32 - SKIP_SRC 44 68 32 - COPY_4_N [3] 80 44 - SKIP_DST 4 80 48 - COPY_4_N [3] 92 60 - SKIP_SRC_DST_SAME 4 96 64 - REMAPPER FlagRemapper@0x093009a0 98 68 - SKIP_SRC -4 94 68 - REMAPPER EnumRemapper@0x093011a0 96 72 - SKIP_SRC 4 100 72 - REMAPPER FlagRemapper@0x09301670 104 76 - SKIP_SRC -104 0 76 - REMAPPER TypeCopyRemapper Array<TObjPtr<String>> 12 88 - SKIP_SRC 40 52 88 - REMAPPER TypeCopyRemapper Array<Int32> 64 100 - SKIP_SRC -40 24 100 - REMAPPER_N EnumRemapper@0x09301d40 [3] 36 112 - REMAPPER_N FlagRemapper@0x09301670 [4] 52 128 - DONE
The code produced above came from producing a remapper between the two classes below. The classes have no purpose other than to test out the system in the test harness.
enum class SrcEnum: Int8 { A = 10, B = 20, C = 93 }; enum class DstEnum: Int16 { A = 11, B = -2, C = -1 }; enum class SrcEnumFlag:UInt16 { R = 0x0004, G = 0x0800, B = 0x0010, A = 0x8000, }; enum class DstEnumFlag:UInt32 { R = 0x80000000, G = 0x00000020, B = 0x00004000, A = 0x00000001, }; class SrcClass { public: TArray<StringRef> m_stringArray; Float32 m_arrayConvert[3]; TEnum<ESrcEnum, UInt32> m_tempEnumArray[3]; TEnumFlags<ESrcEnumFlag, UInt32> m_tempFlagsArray[4]; TArray<Int> m_intArray; Int m_a; Vec3 m_vecArray[2]; ESrcEnum m_enum; TEnum<ESrcEnum, UInt16> m_tempEnum; ESrcEnumFlag m_flags; TEnumFlags<ESrcEnumFlag, UInt32> m_tempFlags; StringRef m_string; }; class DstClass { public: StringRef m_string; EDstEnum m_enum; UInt8 m_a; Float64 m_arrayConvert[3]; Vec4 m_vecArray[2]; EDstEnumFlag m_flags; TEnum<EDstEnum, UInt32> m_tempEnum; TEnumFlags<EDstEnumFlag, UInt32> m_tempFlags; TArray<StringRef> m_stringArray; TArray<Int> m_intArray; TEnum<EDstEnum, UInt32> m_tempEnumArray[3]; TEnumFlags<EDstEnumFlag, UInt32> m_tempFlagsArray[4]; };