UE4(虚幻4)中的TSignedIntType 和 TUnsignedIntType
TSignedIntType 和 TUnsignedIntType作者:PP屁屁用途TSignedIntType用来根据字节数,传出自己想要的int类型TUnsignedIntType用来根据字节数,传出自己想要的unsigned int类型目的基于不同平台的C++运行库相关的API进行封装,以下为Windows举例C++运行库底层确实对 不同位数 的数据给予了不同的 APIUnreal 对其做了
·
TSignedIntType 和 TUnsignedIntType
作者:PP屁屁
用途
- TSignedIntType
- 用来根据字节数,传出自己想要的int类型
- TUnsignedIntType
- 用来根据字节数,传出自己想要的unsigned int类型
目的
- 基于不同平台的C++运行库相关的API进行封装,以下为Windows举例
- C++运行库底层确实对 不同位数 的数据给予了不同的 API
- Unreal 对其做了 跨平台的封装
- 位于 intrin0.inl.h 文件 150行
__MACHINEWVMPURE(long _InterlockedCompareExchange(long volatile * _Destination, long _Exchange, long _Comparand))
__MACHINE(short _InterlockedCompareExchange16(short volatile * _Destination, short _Exchange, short _Comparand))
__MACHINEARM_ARM64(short _InterlockedCompareExchange16_acq(short volatile * _Destination, short _Exchange, short _Comparand))
__MACHINEARM_ARM64(short _InterlockedCompareExchange16_nf(short volatile * _Destination, short _Exchange, short _Comparand))
__MACHINEARM_ARM64(short _InterlockedCompareExchange16_rel(short volatile * _Destination, short _Exchange, short _Comparand))
__MACHINE(__int64 _InterlockedCompareExchange64(__int64 volatile * _Destination, __int64 _Exchange, __int64 _Comparand))
__MACHINEARM_ARM64(__int64 _InterlockedCompareExchange64_acq(__int64 volatile * _Destination, __int64 _Exchange, __int64 _Comparand))
__MACHINEARM_ARM64(__int64 _InterlockedCompareExchange64_nf(__int64 volatile * _Destination, __int64 _Exchange, __int64 _Comparand))
__MACHINEARM_ARM64(__int64 _InterlockedCompareExchange64_rel(__int64 volatile * _Destination, __int64 _Exchange, __int64 _Comparand))
__MACHINE(char _InterlockedCompareExchange8(char volatile * _Destination, char _Exchange, char _Comparand))
__MACHINEARM_ARM64(char _InterlockedCompareExchange8_acq(char volatile * _Destination, char _Exchange, char _Comparand))
__MACHINEARM_ARM64(char _InterlockedCompareExchange8_nf(char volatile * _Destination, char _Exchange, char _Comparand))
__MACHINEARM_ARM64(char _InterlockedCompareExchange8_rel(char volatile * _Destination, char _Exchange, char _Comparand))
简单用法
可用于多级泛型嵌套
template<typename T>
void GetAll()
{
TSignedIntType_T<sizeof(T)> t;
DebugToolsNameSpace::PrintAllMessage("TSignedIntType_T<sizeof(MyTestStruct)>", typeid(t).name());
TUnsignedIntType_T<sizeof(T)> t;
DebugToolsNameSpace::PrintAllMessage("TSignedIntType_T<sizeof(MyTestStruct)>", typeid(t).name());
}
void main()
{
GetAll<double>();
}
实际使用场景(代码抽取)
- 实际使用场景在Unreal内置的原子操作里面有使用
- 基于不同平台的C++运行库相关的API进行封装
intType.h
//intType.h
template <int NumBytes>
struct TSignedIntType
{
};
template <> struct TSignedIntType<1> { using Type = int8; };
template <> struct TSignedIntType<2> { using Type = int16; };
template <> struct TSignedIntType<4> { using Type = int32; };
template <> struct TSignedIntType<8> { using Type = int64; };
/**
* Helper for TSignedIntType which expands out to the nested Type.
*/
template <int NumBytes>
using TSignedIntType_T = typename TSignedIntType<NumBytes>::Type;
Atomic.h 48行
//Atomic.h 48行
template <typename T>
using TUnderlyingIntegerType_T = TSignedIntType_T<sizeof(T)>;
Atomic.h 68行
//Atomic.h 68行
template <typename T>
FORCEINLINE T Load(const volatile T* Element)
{
auto Result = FPlatformAtomics::AtomicRead((volatile TUnderlyingIntegerType_T<T>*)Element);
return *(const T*)&Result;
}
源码分析
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
/**
* Type trait which yields a signed integer type of a given number of bytes.
* If there is no such type, the Type member type will be absent, allowing it to be used in SFINAE contexts.
*/
template <int NumBytes>
struct TSignedIntType
{
};
template <> struct TSignedIntType<1> { using Type = int8; };
template <> struct TSignedIntType<2> { using Type = int16; };
template <> struct TSignedIntType<4> { using Type = int32; };
template <> struct TSignedIntType<8> { using Type = int64; };
/**
* Helper for TSignedIntType which expands out to the nested Type.
*/
template <int NumBytes>
using TSignedIntType_T = typename TSignedIntType<NumBytes>::Type;
/**
* Type trait which yields an unsigned integer type of a given number of bytes.
* If there is no such type, the Type member type will be absent, allowing it to be used in SFINAE contexts.
*/
template <int NumBytes>
struct TUnsignedIntType
{
};
template <> struct TUnsignedIntType<1> { using Type = uint8; };
template <> struct TUnsignedIntType<2> { using Type = uint16; };
template <> struct TUnsignedIntType<4> { using Type = uint32; };
template <> struct TUnsignedIntType<8> { using Type = uint64; };
/**
* Helper for TUnsignedIntType which expands out to the nested Type.
*/
template <int NumBytes>
using TUnsignedIntType_T = typename TUnsignedIntType<NumBytes>::Type;
- TSignedIntType 和 TUnsignedIntType 通过对传入的模板参数的 具体占用字节数 进行特化,特化出了4种类型。
- 其实我们可以看到 Using 的一种实际做法在 泛型编程 中,可以将起别名的行为用来对被起别名的类型进行行为修改。
更多推荐
所有评论(0)