1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-01-19 03:57:14 +01:00

Reduce duplicate code from dynamic comparisons and prepare the implementation to be used for other metamethods types.

This commit is contained in:
Sandu Liviu Catalin 2016-08-24 19:47:10 +03:00
parent 99da8892a4
commit adde1e852a

View File

@ -1551,19 +1551,19 @@ void ImportModuleAPI(PluginFuncs * vcapi, CCStr mod);
#endif // SQMOD_PLUGIN_API #endif // SQMOD_PLUGIN_API
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* Default class for checking if the argument on the stack matches the requested type. * Helper class used to check if a certain operation is possible on the specified argument.
*/ */
template < typename U > struct SqCmpArg template < typename U > struct SqDynamicArg
{ {
static inline bool CanPop(HSQUIRRELVM vm) static inline bool CanPop(HSQUIRRELVM vm)
{ {
return (sq_gettype(vm, 2) == OT_INSTANCE); return (sq_gettype(vm, 2) == OT_INSTANCE);
} }
template < typename T > static inline Int32 Compare(const T & val, HSQUIRRELVM vm) template < typename T > static inline Int32 Cmp(const T & val, HSQUIRRELVM vm)
{ {
Var< U * > var(vm, 2); Var< U * > var(vm, 2);
// Is this instance valid? // Validate the obtained instance
if (!var.value) if (!var.value)
{ {
STHROWF("No such instance"); STHROWF("No such instance");
@ -1574,19 +1574,19 @@ template < typename U > struct SqCmpArg
}; };
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* Specialization of the argument checking structure. * Instance pointer specializations of the argument checking structure.
*/ */
template < typename U > struct SqCmpArg< U * > template < typename U > struct SqDynamicArg< U * >
{ {
static inline bool CanPop(HSQUIRRELVM vm) static inline bool CanPop(HSQUIRRELVM vm)
{ {
return (sq_gettype(vm, 2) == OT_INSTANCE); return (sq_gettype(vm, 2) == OT_INSTANCE);
} }
template < typename T > static inline Int32 Compare(const T & val, HSQUIRRELVM vm) template < typename T > static inline Int32 Cmp(const T & val, HSQUIRRELVM vm)
{ {
Var< U * > var(vm, 2); Var< U * > var(vm, 2);
// Is this instance valid? // Validate the obtained instance
if (!var.value) if (!var.value)
{ {
STHROWF("No such instance"); STHROWF("No such instance");
@ -1597,352 +1597,143 @@ template < typename U > struct SqCmpArg< U * >
}; };
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* Specialization of the argument checking structure. * Instance pointer specializations of the argument checking structure.
*/ */
template < typename U > struct SqCmpArg< const U * > template < typename U > struct SqDynamicArg< const U * >
{ {
static inline bool CanPop(HSQUIRRELVM vm) static inline bool CanPop(HSQUIRRELVM vm)
{ {
return (sq_gettype(vm, 2) == OT_INSTANCE); return (sq_gettype(vm, 2) == OT_INSTANCE);
} }
template < typename T > static inline Int32 Compare(const T & val, HSQUIRRELVM vm) template < typename T > static inline Int32 Cmp(const T & val, HSQUIRRELVM vm)
{ {
Var< const U * > var(vm, 2); Var< const U * > var(vm, 2);
// Is this instance valid? // Validate the obtained instance
if (!var.value) if (!var.value)
{ {
STHROWF("No such instance"); STHROWF("No such instance");
} }
// Attempt to perform the comparison // Attempt to perform the comparison
return val.Cmp(*var.value); return val.Cmp(var.value);
} }
}; };
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* Specialization of the argument checking structure. * Inherited by the base specializations of the argument checking structure.
*/ */
template < > struct SqCmpArg< std::nullptr_t > template < typename U, SQObjectType SqT > struct SqDynamicArgBase
{ {
static inline bool CanPop(HSQUIRRELVM vm) static inline bool CanPop(HSQUIRRELVM vm)
{ {
return (sq_gettype(vm, 2) == OT_NULL); return (sq_gettype(vm, 2) == SqT);
} }
template < typename T > static inline Int32 Compare(const T & val, HSQUIRRELVM /*vm*/) template < typename T > static inline Int32 Cmp(const T & val, HSQUIRRELVM vm)
{ {
return val.Cmp(nullptr); return val.Cmp(Var< U >(vm, 2).value);
} }
}; };
/* ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
* Specialization of the argument checking structure. template < > struct SqDynamicArg< char >
*/ : public SqDynamicArgBase< char, OT_INTEGER >
template < > struct SqCmpArg< char > { /* ... */ };
{
static inline bool CanPop(HSQUIRRELVM vm)
{
return (sq_gettype(vm, 2) == OT_INTEGER);
}
template < typename T > static inline Int32 Compare(const T & val, HSQUIRRELVM vm) // ------------------------------------------------------------------------------------------------
{ template < > struct SqDynamicArg< signed char >
return val.Cmp(Var< char >(vm, 2).value); : public SqDynamicArgBase< signed char, OT_INTEGER >
} { /* ... */ };
};
// ------------------------------------------------------------------------------------------------
template < > struct SqDynamicArg< unsigned char >
: public SqDynamicArgBase< unsigned char, OT_INTEGER >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynamicArg< signed short >
: public SqDynamicArgBase< signed short, OT_INTEGER >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynamicArg< unsigned short >
: public SqDynamicArgBase< unsigned short, OT_INTEGER >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynamicArg< signed int >
: public SqDynamicArgBase< signed int, OT_INTEGER >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynamicArg< unsigned int >
: public SqDynamicArgBase< unsigned int, OT_INTEGER >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynamicArg< signed long >
: public SqDynamicArgBase< signed long, OT_INTEGER >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynamicArg< unsigned long >
: public SqDynamicArgBase< unsigned long, OT_INTEGER >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynamicArg< signed long long >
: public SqDynamicArgBase< signed long long, OT_INTEGER >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynamicArg< unsigned long long >
: public SqDynamicArgBase< unsigned long long, OT_INTEGER >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynamicArg< float >
: public SqDynamicArgBase< float, OT_FLOAT >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynamicArg< double >
: public SqDynamicArgBase< double, OT_FLOAT >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynamicArg< bool >
: public SqDynamicArgBase< bool, OT_BOOL >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynamicArg< SQChar * >
: public SqDynamicArgBase< SQChar *, OT_STRING >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynamicArg< const SQChar * >
: public SqDynamicArgBase< const SQChar *, OT_STRING >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynamicArg< String >
: public SqDynamicArgBase< String, OT_STRING >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynamicArg< Table >
: public SqDynamicArgBase< Table, OT_TABLE >
{ /* ... */ };
// ------------------------------------------------------------------------------------------------
template < > struct SqDynamicArg< Array >
: public SqDynamicArgBase< Array, OT_ARRAY >
{ /* ... */ };
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* Specialization of the argument checking structure. * Specialization of the argument checking structure for functions.
*/ */
template < > struct SqCmpArg< signed char > template < > struct SqDynamicArg< Function >
{
static inline bool CanPop(HSQUIRRELVM vm)
{
return (sq_gettype(vm, 2) == OT_INTEGER);
}
template < typename T > static inline Int32 Compare(const T & val, HSQUIRRELVM vm)
{
return val.Cmp(Var< signed char >(vm, 2).value);
}
};
/* ------------------------------------------------------------------------------------------------
* Specialization of the argument checking structure.
*/
template < > struct SqCmpArg< unsigned char >
{
static inline bool CanPop(HSQUIRRELVM vm)
{
return (sq_gettype(vm, 2) == OT_INTEGER);
}
template < typename T > static inline Int32 Compare(const T & val, HSQUIRRELVM vm)
{
return val.Cmp(Var< unsigned char >(vm, 2).value);
}
};
/* ------------------------------------------------------------------------------------------------
* Specialization of the argument checking structure.
*/
template < > struct SqCmpArg< signed short >
{
static inline bool CanPop(HSQUIRRELVM vm)
{
return (sq_gettype(vm, 2) == OT_INTEGER);
}
template < typename T > static inline Int32 Compare(const T & val, HSQUIRRELVM vm)
{
return val.Cmp(Var< signed short >(vm, 2).value);
}
};
/* ------------------------------------------------------------------------------------------------
* Specialization of the argument checking structure.
*/
template < > struct SqCmpArg< unsigned short >
{
static inline bool CanPop(HSQUIRRELVM vm)
{
return (sq_gettype(vm, 2) == OT_INTEGER);
}
template < typename T > static inline Int32 Compare(const T & val, HSQUIRRELVM vm)
{
return val.Cmp(Var< unsigned short >(vm, 2).value);
}
};
/* ------------------------------------------------------------------------------------------------
* Specialization of the argument checking structure.
*/
template < > struct SqCmpArg< signed int >
{
static inline bool CanPop(HSQUIRRELVM vm)
{
return (sq_gettype(vm, 2) == OT_INTEGER);
}
template < typename T > static inline Int32 Compare(const T & val, HSQUIRRELVM vm)
{
return val.Cmp(Var< signed int >(vm, 2).value);
}
};
/* ------------------------------------------------------------------------------------------------
* Specialization of the argument checking structure.
*/
template < > struct SqCmpArg< unsigned int >
{
static inline bool CanPop(HSQUIRRELVM vm)
{
return (sq_gettype(vm, 2) == OT_INTEGER);
}
template < typename T > static inline Int32 Compare(const T & val, HSQUIRRELVM vm)
{
return val.Cmp(Var< unsigned int >(vm, 2).value);
}
};
/* ------------------------------------------------------------------------------------------------
* Specialization of the argument checking structure.
*/
template < > struct SqCmpArg< signed long >
{
static inline bool CanPop(HSQUIRRELVM vm)
{
return (sq_gettype(vm, 2) == OT_INTEGER);
}
template < typename T > static inline Int32 Compare(const T & val, HSQUIRRELVM vm)
{
return val.Cmp(Var< signed long >(vm, 2).value);
}
};
/* ------------------------------------------------------------------------------------------------
* Specialization of the argument checking structure.
*/
template < > struct SqCmpArg< unsigned long >
{
static inline bool CanPop(HSQUIRRELVM vm)
{
return (sq_gettype(vm, 2) == OT_INTEGER);
}
template < typename T > static inline Int32 Compare(const T & val, HSQUIRRELVM vm)
{
return val.Cmp(Var< unsigned long >(vm, 2).value);
}
};
/* ------------------------------------------------------------------------------------------------
* Specialization of the argument checking structure.
*/
template < > struct SqCmpArg< signed long long >
{
static inline bool CanPop(HSQUIRRELVM vm)
{
return (sq_gettype(vm, 2) == OT_INTEGER);
}
template < typename T > static inline Int32 Compare(const T & val, HSQUIRRELVM vm)
{
return val.Cmp(Var< signed long long >(vm, 2).value);
}
};
/* ------------------------------------------------------------------------------------------------
* Specialization of the argument checking structure.
*/
template < > struct SqCmpArg< unsigned long long >
{
static inline bool CanPop(HSQUIRRELVM vm)
{
return (sq_gettype(vm, 2) == OT_INTEGER);
}
template < typename T > static inline Int32 Compare(const T & val, HSQUIRRELVM vm)
{
return val.Cmp(Var< unsigned long long >(vm, 2).value);
}
};
/* ------------------------------------------------------------------------------------------------
* Specialization of the argument checking structure.
*/
template < > struct SqCmpArg< float >
{
static inline bool CanPop(HSQUIRRELVM vm)
{
return (sq_gettype(vm, 2) == OT_FLOAT);
}
template < typename T > static inline Int32 Compare(const T & val, HSQUIRRELVM vm)
{
return val.Cmp(Var< float >(vm, 2).value);
}
};
/* ------------------------------------------------------------------------------------------------
* Specialization of the argument checking structure.
*/
template < > struct SqCmpArg< double >
{
static inline bool CanPop(HSQUIRRELVM vm)
{
return (sq_gettype(vm, 2) == OT_FLOAT);
}
template < typename T > static inline Int32 Compare(const T & val, HSQUIRRELVM vm)
{
return val.Cmp(Var< double >(vm, 2).value);
}
};
/* ------------------------------------------------------------------------------------------------
* Specialization of the argument checking structure.
*/
template < > struct SqCmpArg< bool >
{
static inline bool CanPop(HSQUIRRELVM vm)
{
return (sq_gettype(vm, 2) == OT_BOOL);
}
template < typename T > static inline Int32 Compare(const T & val, HSQUIRRELVM vm)
{
return val.Cmp(Var< bool >(vm, 2).value);
}
};
/* ------------------------------------------------------------------------------------------------
* Specialization of the argument checking structure.
*/
template < > struct SqCmpArg< SQChar * >
{
static inline bool CanPop(HSQUIRRELVM vm)
{
return (sq_gettype(vm, 2) == OT_STRING);
}
template < typename T > static inline Int32 Compare(const T & val, HSQUIRRELVM vm)
{
return val.Cmp(Var< SQChar * >(vm, 2).value);
}
};
/* ------------------------------------------------------------------------------------------------
* Specialization of the argument checking structure.
*/
template < > struct SqCmpArg< const SQChar * >
{
static inline bool CanPop(HSQUIRRELVM vm)
{
return (sq_gettype(vm, 2) == OT_STRING);
}
template < typename T > static inline Int32 Compare(const T & val, HSQUIRRELVM vm)
{
return val.Cmp(Var< const SQChar * >(vm, 2).value);
}
};
/* ------------------------------------------------------------------------------------------------
* Specialization of the argument checking structure.
*/
template < > struct SqCmpArg< String >
{
static inline bool CanPop(HSQUIRRELVM vm)
{
return (sq_gettype(vm, 2) == OT_STRING);
}
template < typename T > static inline Int32 Compare(const T & val, HSQUIRRELVM vm)
{
return val.Cmp(Var< String >(vm, 2).value);
}
};
/* ------------------------------------------------------------------------------------------------
* Specialization of the argument checking structure.
*/
template < > struct SqCmpArg< Table >
{
static inline bool CanPop(HSQUIRRELVM vm)
{
return (sq_gettype(vm, 2) == OT_TABLE);
}
template < typename T > static inline Int32 Compare(const T & val, HSQUIRRELVM vm)
{
return val.Cmp(Var< Table >(vm, 2).value);
}
};
/* ------------------------------------------------------------------------------------------------
* Specialization of the argument checking structure.
*/
template < > struct SqCmpArg< Array >
{
static inline bool CanPop(HSQUIRRELVM vm)
{
return (sq_gettype(vm, 2) == OT_ARRAY);
}
template < typename T > static inline Int32 Compare(const T & val, HSQUIRRELVM vm)
{
return val.Cmp(Var< Array >(vm, 2).value);
}
};
/* ------------------------------------------------------------------------------------------------
* Specialization of the argument checking structure.
*/
template < > struct SqCmpArg< Function >
{ {
static inline bool CanPop(HSQUIRRELVM vm) static inline bool CanPop(HSQUIRRELVM vm)
{ {
@ -1950,28 +1741,44 @@ template < > struct SqCmpArg< Function >
return (type == OT_CLOSURE || type == OT_NATIVECLOSURE); return (type == OT_CLOSURE || type == OT_NATIVECLOSURE);
} }
template < typename T > static inline Int32 Compare(const T & val, HSQUIRRELVM vm) template < typename T > static inline Int32 Cmp(const T & val, HSQUIRRELVM vm)
{ {
return val.Cmp(Var< Function >(vm, 2).value); return val.Cmp(Var< Function >(vm, 2).value);
} }
}; };
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* Specialization of the argument checking structure. * Specialization of the argument checking structure for objects.
*/ */
template < > struct SqCmpArg< Object > template < > struct SqDynamicArg< Object >
{ {
static inline bool CanPop(HSQUIRRELVM /*vm*/) static inline bool CanPop(HSQUIRRELVM /*vm*/)
{ {
return true; // Objects can use any type. return true; // Objects can use any type.
} }
template < typename T > static inline Int32 Compare(const T & val, HSQUIRRELVM vm) template < typename T > static inline Int32 Cmp(const T & val, HSQUIRRELVM vm)
{ {
return val.Cmp(Var< Object >(vm, 2).value); return val.Cmp(Var< Object >(vm, 2).value);
} }
}; };
/* ------------------------------------------------------------------------------------------------
* Specialization of the argument checking structure for null.
*/
template < > struct SqDynamicArg< std::nullptr_t >
{
static inline bool CanPop(HSQUIRRELVM vm)
{
return (sq_gettype(vm, 2) == OT_NULL);
}
template < typename T > static inline Int32 Cmp(const T & val, HSQUIRRELVM /*vm*/)
{
return val.Cmp(nullptr);
}
};
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* Common function used to compare one type of instance with a couple of other types. * Common function used to compare one type of instance with a couple of other types.
*/ */
@ -2000,17 +1807,17 @@ template < typename U, typename... Ts > struct SqCmpImpl< U, Ts... >
{ {
typedef typename std::decay< U >::type ArgType; typedef typename std::decay< U >::type ArgType;
// Can the stack value be used with the current type? // Can the stack value be used with the current type?
if (SqCmpArg< ArgType >::CanPop(vm)) if (SqDynamicArg< ArgType >::CanPop(vm))
{ {
// If not an instance then don't use a try catch block // If not an instance then don't use a try catch block
if (sq_gettype(vm, 2) != OT_INSTANCE) if (sq_gettype(vm, 2) != OT_INSTANCE)
{ {
return SqCmpArg< ArgType >::Compare(val, vm); return SqDynamicArg< ArgType >::Cmp(val, vm);
} }
// Instances require a try/catch block since we can't differentiate types // Instances require a try/catch block since we can't differentiate types
try try
{ {
return SqCmpArg< ArgType >::Compare(val, vm); return SqDynamicArg< ArgType >::Cmp(val, vm);
} }
catch (const Sqrat::Exception & e) catch (const Sqrat::Exception & e)
{ {