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:
parent
99da8892a4
commit
adde1e852a
@ -1551,19 +1551,19 @@ void ImportModuleAPI(PluginFuncs * vcapi, CCStr mod);
|
||||
#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)
|
||||
{
|
||||
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);
|
||||
// Is this instance valid?
|
||||
// Validate the obtained instance
|
||||
if (!var.value)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
// Is this instance valid?
|
||||
// Validate the obtained instance
|
||||
if (!var.value)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
// Is this instance valid?
|
||||
// Validate the obtained instance
|
||||
if (!var.value)
|
||||
{
|
||||
STHROWF("No such instance");
|
||||
}
|
||||
// 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)
|
||||
{
|
||||
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 SqCmpArg< char >
|
||||
{
|
||||
static inline bool CanPop(HSQUIRRELVM vm)
|
||||
{
|
||||
return (sq_gettype(vm, 2) == OT_INTEGER);
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template < > struct SqDynamicArg< char >
|
||||
: public SqDynamicArgBase< char, OT_INTEGER >
|
||||
{ /* ... */ };
|
||||
|
||||
template < typename T > static inline Int32 Compare(const T & val, HSQUIRRELVM vm)
|
||||
{
|
||||
return val.Cmp(Var< char >(vm, 2).value);
|
||||
}
|
||||
};
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template < > struct SqDynamicArg< signed char >
|
||||
: 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 >
|
||||
{
|
||||
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 >
|
||||
template < > struct SqDynamicArg< Function >
|
||||
{
|
||||
static inline bool CanPop(HSQUIRRELVM vm)
|
||||
{
|
||||
@ -1950,28 +1741,44 @@ template < > struct SqCmpArg< Function >
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* 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*/)
|
||||
{
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* 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.
|
||||
*/
|
||||
@ -2000,17 +1807,17 @@ template < typename U, typename... Ts > struct SqCmpImpl< U, Ts... >
|
||||
{
|
||||
typedef typename std::decay< U >::type ArgType;
|
||||
// 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 (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
|
||||
try
|
||||
{
|
||||
return SqCmpArg< ArgType >::Compare(val, vm);
|
||||
return SqDynamicArg< ArgType >::Cmp(val, vm);
|
||||
}
|
||||
catch (const Sqrat::Exception & e)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user