mirror of
https://github.com/libretro/ppsspp.git
synced 2025-02-19 16:31:20 +00:00
Merge pull request #2044 from unknownbrackets/mem-pointers
Use PSPPointer in a few more places
This commit is contained in:
commit
1d0d13509c
@ -124,34 +124,15 @@ PSPOskDialog::PSPOskDialog() : PSPDialog() {
|
||||
PSPOskDialog::~PSPOskDialog() {
|
||||
}
|
||||
|
||||
void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, const u32 em_address)
|
||||
void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, const PSPPointer<wchar_t> em_address)
|
||||
{
|
||||
char stringBuffer[2048];
|
||||
char *string = stringBuffer;
|
||||
|
||||
if (em_address == 0)
|
||||
if (!em_address.Valid())
|
||||
{
|
||||
_string = "";
|
||||
return;
|
||||
}
|
||||
|
||||
u16 *src = (u16 *) Memory::GetPointer(em_address);
|
||||
int c;
|
||||
while (c = *src++)
|
||||
{
|
||||
if (c < 0x80)
|
||||
*string++ = c;
|
||||
else if (c < 0x800) {
|
||||
*string++ = 0xC0 | (c >> 6);
|
||||
*string++ = 0x80 | (c & 0x3F);
|
||||
} else {
|
||||
*string++ = 0xE0 | (c >> 12);
|
||||
*string++ = 0x80 | ((c >> 6) & 0x3F);
|
||||
*string++ = 0x80 | (c & 0x3F);
|
||||
}
|
||||
}
|
||||
*string++ = '\0';
|
||||
_string = stringBuffer;
|
||||
ConvertUCS2ToUTF8(_string, &em_address[0]);
|
||||
}
|
||||
|
||||
void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, wchar_t* input)
|
||||
@ -160,7 +141,7 @@ void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, wchar_t* input)
|
||||
char *string = stringBuffer;
|
||||
|
||||
int c;
|
||||
while (c = *input++)
|
||||
while ((c = *input++) != 0)
|
||||
{
|
||||
if (c < 0x80)
|
||||
*string++ = c;
|
||||
@ -189,16 +170,16 @@ int PSPOskDialog::Init(u32 oskPtr)
|
||||
return -1;
|
||||
}
|
||||
|
||||
oskParams = Memory::GetStruct<SceUtilityOskParams>(oskPtr);
|
||||
oskParams = oskPtr;
|
||||
if (oskParams->base.size != sizeof(SceUtilityOskParams))
|
||||
{
|
||||
ERROR_LOG(HLE, "sceUtilityOskInitStart: invalid size (%d)", oskParams->base.size);
|
||||
return SCE_ERROR_UTILITY_INVALID_PARAM_SIZE;
|
||||
}
|
||||
// Also seems to crash.
|
||||
if (!Memory::IsValidAddress(oskParams->fieldPtr))
|
||||
if (!oskParams->fields.Valid())
|
||||
{
|
||||
ERROR_LOG_REPORT(HLE, "sceUtilityOskInitStart: invalid field data (%08x)", oskParams->fieldPtr);
|
||||
ERROR_LOG_REPORT(HLE, "sceUtilityOskInitStart: invalid field data (%08x)", oskParams->fields.ptr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -211,26 +192,19 @@ int PSPOskDialog::Init(u32 oskPtr)
|
||||
selectedChar = 0;
|
||||
currentKeyboard = OSK_KEYBOARD_LATIN_LOWERCASE;
|
||||
|
||||
Memory::ReadStruct(oskParams->fieldPtr, &oskData);
|
||||
ConvertUCS2ToUTF8(oskDesc, oskData.descPtr);
|
||||
ConvertUCS2ToUTF8(oskIntext, oskData.intextPtr);
|
||||
ConvertUCS2ToUTF8(oskOuttext, oskData.outtextPtr);
|
||||
ConvertUCS2ToUTF8(oskDesc, oskParams->fields[0].desc);
|
||||
ConvertUCS2ToUTF8(oskIntext, oskParams->fields[0].intext);
|
||||
ConvertUCS2ToUTF8(oskOuttext, oskParams->fields[0].outtext);
|
||||
|
||||
i_level = 0;
|
||||
|
||||
inputChars = L"";
|
||||
|
||||
if (oskData.intextPtr) {
|
||||
u16 *src = (u16 *) Memory::GetPointer(oskData.intextPtr);
|
||||
if (oskParams->fields[0].intext.Valid()) {
|
||||
auto src = oskParams->fields[0].intext;
|
||||
int c;
|
||||
while (c = *src++)
|
||||
{
|
||||
while ((c = *src++) != 0)
|
||||
inputChars += c;
|
||||
if(c == 0x00)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Eat any keys pressed before the dialog inited.
|
||||
@ -307,10 +281,10 @@ std::wstring PSPOskDialog::CombinationKorean(bool isInput)
|
||||
}
|
||||
}
|
||||
} else if(i_level == 2) {
|
||||
u32 tmp = GetIndex(kor_vowel, sw);
|
||||
int tmp = GetIndex(kor_vowel, sw);
|
||||
if(tmp != -1) {
|
||||
int tmp2 = -1;
|
||||
for(int j = 0; j < sizeof(kor_vowelCom) / 4; j+=3) {
|
||||
for(size_t j = 0; j < sizeof(kor_vowelCom) / 4; j+=3) {
|
||||
if(kor_vowelCom[j] == tmp && kor_vowelCom[j + 1] == i_value[1]) {
|
||||
tmp2 = kor_vowelCom[j + 2];
|
||||
break;
|
||||
@ -337,7 +311,7 @@ std::wstring PSPOskDialog::CombinationKorean(bool isInput)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
u32 tmp = GetIndex(kor_lcons, sw);
|
||||
int tmp = GetIndex(kor_lcons, sw);
|
||||
|
||||
if(tmp == -1) {
|
||||
string += inputChars[i];
|
||||
@ -367,10 +341,10 @@ std::wstring PSPOskDialog::CombinationKorean(bool isInput)
|
||||
}
|
||||
}
|
||||
} else if(i_level == 3) {
|
||||
u32 tmp = GetIndex(kor_lcons, sw);
|
||||
int tmp = GetIndex(kor_lcons, sw);
|
||||
if(tmp != -1) {
|
||||
int tmp2 = -1;
|
||||
for(int j = 0; j < sizeof(kor_lconsCom) / 4; j+=3) {
|
||||
for(size_t j = 0; j < sizeof(kor_lconsCom) / 4; j+=3) {
|
||||
if(kor_lconsCom[j] == tmp && kor_lconsCom[j + 1] == i_value[2]) {
|
||||
tmp2 = kor_lconsCom[j + 2];
|
||||
break;
|
||||
@ -402,7 +376,7 @@ std::wstring PSPOskDialog::CombinationKorean(bool isInput)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
u32 tmp = GetIndex(kor_vowel, sw);
|
||||
int tmp = GetIndex(kor_vowel, sw);
|
||||
if(tmp == -1) {
|
||||
string += inputChars[i];
|
||||
if (inputChars.size() < FieldMaxLength()) {
|
||||
@ -422,9 +396,9 @@ std::wstring PSPOskDialog::CombinationKorean(bool isInput)
|
||||
} else {
|
||||
if (inputChars.size() < FieldMaxLength()) {
|
||||
int tmp2 = -1;
|
||||
for(int j = 0; j < sizeof(kor_lconsSpr) / 4; j+=3) {
|
||||
for(size_t j = 0; j < sizeof(kor_lconsSpr) / 4; j+=3) {
|
||||
if(kor_lconsSpr[j] == i_value[2]) {
|
||||
tmp2 = j;
|
||||
tmp2 = (int)j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -441,7 +415,7 @@ std::wstring PSPOskDialog::CombinationKorean(bool isInput)
|
||||
i_level = 2;
|
||||
}
|
||||
} else {
|
||||
u32 tmp2 = GetIndex(kor_cons, kor_lcons[i_value[2]]);
|
||||
int tmp2 = GetIndex(kor_cons, kor_lcons[i_value[2]]);
|
||||
|
||||
if(tmp2 != -1) {
|
||||
u16 code = 0xAC00 + i_value[0] * 0x24C + i_value[1] * 0x1C;
|
||||
@ -583,7 +557,7 @@ void PSPOskDialog::RemoveKorean()
|
||||
else if(i_level == 2)
|
||||
{
|
||||
int tmp = -1;
|
||||
for(int i = 2; i < sizeof(kor_vowelCom) / 4; i+=3)
|
||||
for(size_t i = 2; i < sizeof(kor_vowelCom) / 4; i+=3)
|
||||
{
|
||||
if(kor_vowelCom[i] == i_value[1])
|
||||
{
|
||||
@ -607,7 +581,7 @@ void PSPOskDialog::RemoveKorean()
|
||||
else if(i_level == 3)
|
||||
{
|
||||
int tmp = -1;
|
||||
for(int i = 2; i < sizeof(kor_lconsCom) / 4; i+=3)
|
||||
for(size_t i = 2; i < sizeof(kor_lconsCom) / 4; i+=3)
|
||||
{
|
||||
if(kor_lconsCom[i] == i_value[2])
|
||||
{
|
||||
@ -631,9 +605,9 @@ void PSPOskDialog::RemoveKorean()
|
||||
}
|
||||
}
|
||||
|
||||
u32 PSPOskDialog::GetIndex(const wchar_t* src, wchar_t ch)
|
||||
int PSPOskDialog::GetIndex(const wchar_t* src, wchar_t ch)
|
||||
{
|
||||
for(u32 i = 0; i < wcslen(src); i++)
|
||||
for(int i = 0, end = (int)wcslen(src); i < end; i++)
|
||||
{
|
||||
if(src[i] == ch)
|
||||
{
|
||||
@ -646,9 +620,9 @@ u32 PSPOskDialog::GetIndex(const wchar_t* src, wchar_t ch)
|
||||
|
||||
u32 PSPOskDialog::FieldMaxLength()
|
||||
{
|
||||
if (oskData.outtextlimit > oskData.outtextlength - 1 || oskData.outtextlimit == 0)
|
||||
return oskData.outtextlength - 1;
|
||||
return oskData.outtextlimit;
|
||||
if (oskParams->fields[0].outtextlimit > oskParams->fields[0].outtextlength - 1 || oskParams->fields[0].outtextlimit == 0)
|
||||
return oskParams->fields[0].outtextlength - 1;
|
||||
return oskParams->fields[0].outtextlimit;
|
||||
}
|
||||
|
||||
void PSPOskDialog::RenderKeyboard()
|
||||
@ -835,33 +809,21 @@ int PSPOskDialog::Update()
|
||||
status = SCE_UTILITY_STATUS_SHUTDOWN;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < oskData.outtextlength; ++i)
|
||||
wchar_t *outText = oskParams->fields[0].outtext;
|
||||
for (u32 i = 0, end = oskParams->fields[0].outtextlength; i < end; ++i)
|
||||
{
|
||||
u16 value = 0;
|
||||
if (i < inputChars.size())
|
||||
value = inputChars[i];
|
||||
Memory::Write_U16(value, oskData.outtextPtr + (2 * i));
|
||||
outText[i] = inputChars[i];
|
||||
outText[i] = value;
|
||||
}
|
||||
|
||||
oskParams->base.result = 0;
|
||||
oskData.result = PSP_UTILITY_OSK_RESULT_CHANGED;
|
||||
Memory::WriteStruct(oskParams->fieldPtr, &oskData);
|
||||
oskParams->fields[0].result = PSP_UTILITY_OSK_RESULT_CHANGED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void DoBasePointer(PointerWrap &p, T **ptr)
|
||||
{
|
||||
u32 addr = *ptr == NULL ? 0 : (u8 *) *ptr - Memory::base;
|
||||
p.Do(addr);
|
||||
if (addr == 0)
|
||||
*ptr = NULL;
|
||||
else
|
||||
*ptr = Memory::GetStruct<T>(addr);
|
||||
|
||||
}
|
||||
|
||||
int PSPOskDialog::Shutdown(bool force)
|
||||
{
|
||||
if (status != SCE_UTILITY_STATUS_FINISHED && !force)
|
||||
@ -875,8 +837,7 @@ int PSPOskDialog::Shutdown(bool force)
|
||||
void PSPOskDialog::DoState(PointerWrap &p)
|
||||
{
|
||||
PSPDialog::DoState(p);
|
||||
DoBasePointer(p, &oskParams);
|
||||
p.Do(oskData);
|
||||
p.Do(oskParams);
|
||||
p.Do(oskDesc);
|
||||
p.Do(oskIntext);
|
||||
p.Do(oskOuttext);
|
||||
|
@ -94,7 +94,7 @@ enum SceUtilityOskInputType
|
||||
/**
|
||||
* OSK Field data
|
||||
*/
|
||||
typedef struct _SceUtilityOskData
|
||||
struct SceUtilityOskData
|
||||
{
|
||||
/** Unknown. Pass 0. */
|
||||
int unk_00;
|
||||
@ -111,19 +111,18 @@ typedef struct _SceUtilityOskData
|
||||
/** Unknown. Pass 0. */
|
||||
int unk_24;
|
||||
/** Description text */
|
||||
u32 descPtr;
|
||||
PSPPointer<wchar_t> desc;
|
||||
/** Initial text */
|
||||
u32 intextPtr;
|
||||
PSPPointer<wchar_t> intext;
|
||||
// Length, in unsigned shorts, including the terminator.
|
||||
u32 outtextlength;
|
||||
/** Pointer to the output text */
|
||||
u32 outtextPtr;
|
||||
PSPPointer<wchar_t> outtext;
|
||||
/** Result. One of ::SceUtilityOskResult */
|
||||
int result;
|
||||
// Number of characters to allow, not including terminator (if less than outtextlength - 1.)
|
||||
u32 outtextlimit;
|
||||
|
||||
} SceUtilityOskData;
|
||||
};
|
||||
|
||||
// Parameters to sceUtilityOskInitStart
|
||||
struct SceUtilityOskParams
|
||||
@ -132,7 +131,7 @@ struct SceUtilityOskParams
|
||||
// Number of fields.
|
||||
int fieldCount;
|
||||
// Pointer to an array of fields (see SceUtilityOskData.)
|
||||
u32 fieldPtr;
|
||||
PSPPointer<SceUtilityOskData> fields;
|
||||
SceUtilityOskState state;
|
||||
// Maybe just padding?
|
||||
int unk_60;
|
||||
@ -164,7 +163,7 @@ public:
|
||||
virtual int Shutdown(bool force = false);
|
||||
virtual void DoState(PointerWrap &p);
|
||||
private:
|
||||
void ConvertUCS2ToUTF8(std::string& _string, const u32 em_address);
|
||||
void ConvertUCS2ToUTF8(std::string& _string, const PSPPointer<wchar_t> em_address);
|
||||
void ConvertUCS2ToUTF8(std::string& _string, wchar_t* input);
|
||||
void RenderKeyboard();
|
||||
|
||||
@ -173,10 +172,9 @@ private:
|
||||
void RemoveKorean(); // for Korean character removal
|
||||
|
||||
u32 FieldMaxLength();
|
||||
u32 GetIndex(const wchar_t* src, wchar_t ch);
|
||||
int GetIndex(const wchar_t* src, wchar_t ch);
|
||||
|
||||
SceUtilityOskParams *oskParams;
|
||||
SceUtilityOskData oskData;
|
||||
PSPPointer<SceUtilityOskParams> oskParams;
|
||||
std::string oskDesc;
|
||||
std::string oskIntext;
|
||||
std::string oskOuttext;
|
||||
|
@ -844,13 +844,13 @@ int SavedataParam::GetFilesList(SceUtilitySavedataParam *param)
|
||||
return SCE_UTILITY_SAVEDATA_ERROR_RW_BAD_STATUS;
|
||||
}
|
||||
|
||||
if (!Memory::IsValidAddress(param->fileListAddr)) {
|
||||
ERROR_LOG_REPORT(HLE, "SavedataParam::GetFilesList(): bad fileList address %08x", param->fileListAddr);
|
||||
if (!param->fileList.Valid()) {
|
||||
ERROR_LOG_REPORT(HLE, "SavedataParam::GetFilesList(): bad fileList address %08x", param->fileList.ptr);
|
||||
// Should crash.
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto fileList = Memory::GetStruct<SceUtilitySavedataFileListInfo>(param->fileListAddr);
|
||||
auto &fileList = param->fileList;
|
||||
if (fileList->secureEntries.Valid() && fileList->maxSecureEntries > 99) {
|
||||
ERROR_LOG_REPORT(HLE, "SavedataParam::GetFilesList(): too many secure entries, %d", fileList->maxSecureEntries);
|
||||
return SCE_UTILITY_SAVEDATA_ERROR_RW_BAD_PARAMS;
|
||||
|
@ -186,7 +186,7 @@ struct SceUtilitySavedataParam
|
||||
u32 idListAddr;
|
||||
|
||||
// Function 12 FILES
|
||||
u32 fileListAddr;
|
||||
PSPPointer<SceUtilitySavedataFileListInfo> fileList;
|
||||
|
||||
// Function 22 GETSIZES
|
||||
u32 sizeAddr;
|
||||
|
@ -82,22 +82,6 @@ struct Mutex : public KernelObject
|
||||
};
|
||||
|
||||
|
||||
struct NativeLwMutex
|
||||
{
|
||||
SceSize size;
|
||||
char name[KERNELOBJECT_MAX_NAME_LENGTH + 1];
|
||||
SceUInt attr;
|
||||
SceUID uid;
|
||||
u32 workareaPtr;
|
||||
int initialCount;
|
||||
// Not kept up to date.
|
||||
int currentCount;
|
||||
// Not kept up to date.
|
||||
SceUID lockThread;
|
||||
// Not kept up to date.
|
||||
int numWaitThreads;
|
||||
};
|
||||
|
||||
struct NativeLwMutexWorkarea
|
||||
{
|
||||
int lockLevel;
|
||||
@ -120,6 +104,22 @@ struct NativeLwMutexWorkarea
|
||||
}
|
||||
};
|
||||
|
||||
struct NativeLwMutex
|
||||
{
|
||||
SceSize size;
|
||||
char name[KERNELOBJECT_MAX_NAME_LENGTH + 1];
|
||||
SceUInt attr;
|
||||
SceUID uid;
|
||||
PSPPointer<NativeLwMutexWorkarea> workarea;
|
||||
int initialCount;
|
||||
// Not kept up to date.
|
||||
int currentCount;
|
||||
// Not kept up to date.
|
||||
SceUID lockThread;
|
||||
// Not kept up to date.
|
||||
int numWaitThreads;
|
||||
};
|
||||
|
||||
struct LwMutex : public KernelObject
|
||||
{
|
||||
const char *GetName() {return nm.name;}
|
||||
@ -732,7 +732,7 @@ int sceKernelCreateLwMutex(u32 workareaPtr, const char *name, u32 attr, int init
|
||||
mutex->nm.name[KERNELOBJECT_MAX_NAME_LENGTH] = 0;
|
||||
mutex->nm.attr = attr;
|
||||
mutex->nm.uid = id;
|
||||
mutex->nm.workareaPtr = workareaPtr;
|
||||
mutex->nm.workarea = workareaPtr;
|
||||
mutex->nm.initialCount = initialCount;
|
||||
auto workarea = Memory::GetStruct<NativeLwMutexWorkarea>(workareaPtr);
|
||||
workarea->init();
|
||||
@ -990,8 +990,7 @@ void __KernelLwMutexEndCallback(SceUID threadID, SceUID prevCallbackId, u32 &ret
|
||||
// TODO: Don't wake up if __KernelCurHasReadyCallbacks()?
|
||||
|
||||
// Attempt to unlock.
|
||||
auto workarea = Memory::GetStruct<NativeLwMutexWorkarea>(mutex->nm.workareaPtr);
|
||||
if (mutex->nm.lockThread == -1 && __KernelUnlockLwMutexForThread(mutex, workarea, threadID, error, 0))
|
||||
if (mutex->nm.lockThread == -1 && __KernelUnlockLwMutexForThread(mutex, mutex->nm.workarea, threadID, error, 0))
|
||||
return;
|
||||
|
||||
// We only check if it timed out if it couldn't unlock.
|
||||
@ -1150,7 +1149,7 @@ int __KernelReferLwMutexStatus(SceUID uid, u32 infoPtr)
|
||||
|
||||
if (Memory::Read_U32(infoPtr) != 0)
|
||||
{
|
||||
auto workarea = Memory::GetStruct<NativeLwMutexWorkarea>(m->nm.workareaPtr);
|
||||
auto workarea = m->nm.workarea;
|
||||
|
||||
u32 error;
|
||||
for (auto iter = m->waitingThreads.begin(); iter != m->waitingThreads.end(); ++iter)
|
||||
|
107
Core/MemMap.h
107
Core/MemMap.h
@ -269,17 +269,82 @@ struct PSPPointer
|
||||
{
|
||||
u32 ptr;
|
||||
|
||||
T &operator*() const
|
||||
inline T &operator*() const
|
||||
{
|
||||
return *(T *)(Memory::base + ptr);
|
||||
}
|
||||
|
||||
T &operator[](int i) const
|
||||
inline T &operator[](int i) const
|
||||
{
|
||||
return *((T *)(Memory::base + ptr) + i);
|
||||
}
|
||||
|
||||
T *operator->() const
|
||||
inline T *operator->() const
|
||||
{
|
||||
return (T *)(Memory::base + ptr);
|
||||
}
|
||||
|
||||
inline PSPPointer<T> operator+(int i) const
|
||||
{
|
||||
PSPPointer other;
|
||||
other.ptr = ptr + i * sizeof(T);
|
||||
return other;
|
||||
}
|
||||
|
||||
inline PSPPointer<T> &operator=(u32 p)
|
||||
{
|
||||
ptr = p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline PSPPointer<T> &operator+=(int i)
|
||||
{
|
||||
ptr = ptr + i * sizeof(T);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline PSPPointer<T> operator-(int i) const
|
||||
{
|
||||
PSPPointer other;
|
||||
other.ptr = ptr - i * sizeof(T);
|
||||
return other;
|
||||
}
|
||||
|
||||
inline PSPPointer<T> &operator-=(int i)
|
||||
{
|
||||
ptr = ptr - i * sizeof(T);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline PSPPointer<T> &operator++()
|
||||
{
|
||||
ptr += sizeof(T);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline PSPPointer<T> operator++(int i)
|
||||
{
|
||||
PSPPointer<T> other;
|
||||
other.ptr = ptr;
|
||||
ptr += sizeof(T);
|
||||
return other;
|
||||
}
|
||||
|
||||
inline PSPPointer<T> &operator--()
|
||||
{
|
||||
ptr -= sizeof(T);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline PSPPointer<T> operator--(int i)
|
||||
{
|
||||
PSPPointer<T> other;
|
||||
other.ptr = ptr;
|
||||
ptr -= sizeof(T);
|
||||
return other;
|
||||
}
|
||||
|
||||
inline operator T*()
|
||||
{
|
||||
return (T *)(Memory::base + ptr);
|
||||
}
|
||||
@ -290,5 +355,41 @@ struct PSPPointer
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline bool operator==(const PSPPointer<T> &lhs, const PSPPointer<T> &rhs)
|
||||
{
|
||||
return lhs.ptr == rhs.ptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool operator!=(const PSPPointer<T> &lhs, const PSPPointer<T> &rhs)
|
||||
{
|
||||
return lhs.ptr != rhs.ptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool operator<(const PSPPointer<T> &lhs, const PSPPointer<T> &rhs)
|
||||
{
|
||||
return lhs.ptr < rhs.ptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool operator>(const PSPPointer<T> &lhs, const PSPPointer<T> &rhs)
|
||||
{
|
||||
return lhs.ptr > rhs.ptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool operator<=(const PSPPointer<T> &lhs, const PSPPointer<T> &rhs)
|
||||
{
|
||||
return lhs.ptr <= rhs.ptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool operator>=(const PSPPointer<T> &lhs, const PSPPointer<T> &rhs)
|
||||
{
|
||||
return lhs.ptr >= rhs.ptr;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user