1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-02-21 20:27:13 +01:00

Improve the String library to reduce the size of the generated executable code.

This commit is contained in:
Sandu Liviu Catalin 2016-09-15 03:03:06 +03:00
parent 501d0884f3
commit 5072f7712c

View File

@ -680,368 +680,180 @@ static SQInteger SqToUppercase(HSQUIRRELVM vm)
} }
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* Known character classifications * Checks if all the characters in the specified string are of the specified class or not.
*/ */
enum struct CharClass static SQInteger AllCharsImpl(HSQUIRRELVM vm, int(*fn)(int))
{ {
IsSpace = 0, static const SQInteger top = sq_gettop(vm);
IsPrint, // Is there a value to process?
IsCntrl, if (top <= 1)
IsUpper, {
IsLower, return sq_throwerror(vm, "Missing string or value");
IsAlpha, }
IsDigit,
IsPunct, // Attempt to retrieve the value from the stack as a string
IsXdigit, StackStrF val(vm, 2);
IsAlnum, // Have we failed to retrieve the string?
IsGraph, if (SQ_FAILED(val.mRes))
IsBlank {
}; return val.mRes; // Propagate the error!
}
// See if we actually have something to search for
else if (!(val.mPtr) || *(val.mPtr) == '\0')
{
// Since there are no other different character then
// we count this as all characters being of this type
sq_pushbool(vm, true);
// We're done here
return 1;
}
// Start iterating characters and find the first that doesn't match
for (CSStr itr = val.mPtr; *itr != '\0'; ++itr)
{
// Call the predicate with the current character
if (fn(*itr) == 0)
{
// This character did not pass the test
sq_pushbool(vm, false);
// We're done here
return 1;
}
}
// All characters passed the test
sq_pushbool(vm, true);
// We're done here
return 1;
}
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* Specialization for the character classifications. * Simple forwarder to minimize templated functions with large body and reduce executable size.
*/ */
template < CharClass > struct CharClassSpec; template < int (*Fn)(int) > static SQInteger AllCharsProxy(HSQUIRRELVM vm)
// ------------------------------------------------------------------------------------------------
template <> struct CharClassSpec< CharClass::IsSpace >
{ {
static inline int Fn(int c) { return std::isspace(c); } return AllCharsImpl(vm, Fn);
static inline bool Eq(int c) { return std::isspace(c) != 0; } }
};
// ------------------------------------------------------------------------------------------------
template <> struct CharClassSpec< CharClass::IsPrint >
{
static inline int Fn(int c) { return std::isprint(c); }
static inline bool Eq(int c) { return std::isprint(c) != 0; }
};
// ------------------------------------------------------------------------------------------------
template <> struct CharClassSpec< CharClass::IsCntrl >
{
static inline int Fn(int c) { return std::iscntrl(c); }
static inline bool Eq(int c) { return std::iscntrl(c) != 0; }
};
// ------------------------------------------------------------------------------------------------
template <> struct CharClassSpec< CharClass::IsUpper >
{
static inline int Fn(int c) { return std::isupper(c); }
static inline bool Eq(int c) { return std::isupper(c) != 0; }
};
// ------------------------------------------------------------------------------------------------
template <> struct CharClassSpec< CharClass::IsLower >
{
static inline int Fn(int c) { return std::islower(c); }
static inline bool Eq(int c) { return std::islower(c) != 0; }
};
// ------------------------------------------------------------------------------------------------
template <> struct CharClassSpec< CharClass::IsAlpha >
{
static inline int Fn(int c) { return std::isalpha(c); }
static inline bool Eq(int c) { return std::isalpha(c) != 0; }
};
// ------------------------------------------------------------------------------------------------
template <> struct CharClassSpec< CharClass::IsDigit >
{
static inline int Fn(int c) { return std::isdigit(c); }
static inline bool Eq(int c) { return std::isdigit(c) != 0; }
};
// ------------------------------------------------------------------------------------------------
template <> struct CharClassSpec< CharClass::IsPunct >
{
static inline int Fn(int c) { return std::ispunct(c); }
static inline bool Eq(int c) { return std::ispunct(c) != 0; }
};
// ------------------------------------------------------------------------------------------------
template <> struct CharClassSpec< CharClass::IsXdigit >
{
static inline int Fn(int c) { return std::isxdigit(c); }
static inline bool Eq(int c) { return std::isxdigit(c) != 0; }
};
// ------------------------------------------------------------------------------------------------
template <> struct CharClassSpec< CharClass::IsAlnum >
{
static inline int Fn(int c) { return std::isalnum(c); }
static inline bool Eq(int c) { return std::isalnum(c) != 0; }
};
// ------------------------------------------------------------------------------------------------
template <> struct CharClassSpec< CharClass::IsGraph >
{
static inline int Fn(int c) { return std::isgraph(c); }
static inline bool Eq(int c) { return std::isgraph(c) != 0; }
};
// ------------------------------------------------------------------------------------------------
template <> struct CharClassSpec< CharClass::IsBlank >
{
static inline int Fn(int c) { return std::isblank(c); }
static inline bool Eq(int c) { return std::isblank(c) != 0; }
};
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* Templated functions for working with character classification functions. * Find the position of the first character that matches the specified class.
*/ */
template < class T > struct StrCType static SQInteger FirstCharImpl(HSQUIRRELVM vm, int(*fn)(int), bool neg)
{ {
/* -------------------------------------------------------------------------------------------- static const SQInteger top = sq_gettop(vm);
* Checks if all the characters in the specified string are of the specified class. // Is there a value to process?
*/ if (top <= 1)
static bool AllCharsImpl(CSStr str)
{ {
// See if we actually have something to search for return sq_throwerror(vm, "Missing string or value");
if(!str || *str == '\0')
{
return false; // Subject to change!
}
// Start iterating characters and find the first that doesn't match
while (*str != '\0')
{
// Call the predicate with the current character
if (T::Fn(*(str++)) == 0)
{
return false; // This character did not pass the test
}
}
// All characters passed the test
return true;
} }
/* -------------------------------------------------------------------------------------------- // Attempt to retrieve the value from the stack as a string
* Extracts and forwards the string argument to the actual implementation. StackStrF val(vm, 2);
*/ // Have we failed to retrieve the string?
static SQInteger AllChars(HSQUIRRELVM vm) if (SQ_FAILED(val.mRes))
{ {
// Attempt to retrieve the value from the stack as a string return val.mRes; // Propagate the error!
StackStrF val(vm, 2); }
// Have we failed to retrieve the string? // See if we actually have something to search for
if (SQ_FAILED(val.mRes)) else if (!(val.mPtr) || *(val.mPtr) == '\0')
{ {
return val.mRes; // Propagate the error! // Since there are no other different character then
} // we count this as no characters being of this type
// Perform the actual check and push the result on the stack sq_pushnull(vm);
sq_pushbool(vm, AllCharsImpl(val.mPtr)); // We're done here
// We have a value to return on the stack
return 1; return 1;
} }
/* -------------------------------------------------------------------------------------------- // Start iterating characters and find the first that matches
* Find the position of the first character that matches the specified class. for (CSStr itr = val.mPtr; *itr != '\0'; ++itr)
*/
static SQInteger FirstCharImpl(CSStr str)
{ {
// See if we actually have something to search for // Call the predicate with the current character
if(!str || *str == '\0') if ((fn(*itr) == 0) == neg)
{ {
return -1; // Subject to change! // This character passed our test, push it's position
sq_pushinteger(vm, itr - val.mPtr);
// We're done here
return 1;
} }
// Start iterating characters and find the first that matches
for (Uint32 n = 0; *str != '\0'; ++n, ++str)
{
// Call the predicate with the current character
if (T::Fn(*str) != 0)
{
// This character passed our test
return static_cast< SQInteger >(n);
}
}
// Unable to locate such character
return -1;
} }
/* -------------------------------------------------------------------------------------------- // Unable to locate such character
* Extracts and forwards the string argument to the actual implementation. sq_pushnull(vm);
*/ // We're done here
static SQInteger FirstChar(HSQUIRRELVM vm) return 1;
}
/* ------------------------------------------------------------------------------------------------
* Simple forwarder to minimize templated functions with large body and reduce executable size.
*/
template < int (*Fn)(int), bool Neg >static SQInteger FirstCharProxy(HSQUIRRELVM vm)
{
return FirstCharImpl(vm, Fn, Neg);
}
/* ------------------------------------------------------------------------------------------------
* Find the position of the last character that matches the specified class.
*/
static SQInteger LastCharImpl(HSQUIRRELVM vm, int(*fn)(int), bool neg)
{
static const SQInteger top = sq_gettop(vm);
// Is there a value to process?
if (top <= 1)
{ {
// Attempt to retrieve the value from the stack as a string return sq_throwerror(vm, "Missing string or value");
StackStrF val(vm, 2); }
// Have we failed to retrieve the string?
if (SQ_FAILED(val.mRes)) // Attempt to retrieve the value from the stack as a string
{ StackStrF val(vm, 2);
return val.mRes; // Propagate the error! // Have we failed to retrieve the string?
} if (SQ_FAILED(val.mRes))
// Perform the actual check and store the resulted value {
SQInteger ret = FirstCharImpl(val.mPtr); return val.mRes; // Propagate the error!
// Have we found anything? }
if (ret >= 0) // See if we actually have something to search for
{ else if (!(val.mPtr) || *(val.mPtr) == '\0')
sq_pushinteger(vm, ret); {
} // Since there are no other different character then
else // we count this as no characters being of this type
{ sq_pushnull(vm);
sq_pushnull(vm); // We're done here
}
// We have a value to return on the stack
return 1; return 1;
} }
/* -------------------------------------------------------------------------------------------- // Start iterating characters and find the first that matches
* Find the position of the first character that doesn't match the specified class. for (CSStr itr = (val.mPtr + val.mLen) - 1; itr >= val.mPtr; --itr)
*/
static SQInteger FirstNotCharImpl(CSStr str)
{ {
// See if we actually have something to search for // Call the predicate with the current character
if(!str || *str == '\0') if ((fn(*itr) == 0) == neg)
{ {
return -1; // Subject to change! // This character passed our test, push it's position
sq_pushinteger(vm, itr - val.mPtr);
// We're done here
return 1;
} }
// Start iterating characters and find the first that doesn't match
for (Uint32 n = 0; *str != '\0'; ++n, ++str)
{
// Call the predicate with the current character
if (T::Fn(*str) == 0)
{
// This character passed our test
return static_cast< SQInteger >(n);
}
}
// Unable to locate such character
return -1;
} }
/* -------------------------------------------------------------------------------------------- // Unable to locate such character
* Extracts and forwards the string argument to the actual implementation. sq_pushnull(vm);
*/ // We're done here
static SQInteger FirstNotChar(HSQUIRRELVM vm) return 1;
{ }
// Attempt to retrieve the value from the stack as a string
StackStrF val(vm, 2);
// Have we failed to retrieve the string?
if (SQ_FAILED(val.mRes))
{
return val.mRes; // Propagate the error!
}
// Perform the actual check and store the resulted value
SQInteger ret = FirstNotCharImpl(val.mPtr);
// Have we found anything?
if (ret >= 0)
{
sq_pushinteger(vm, ret);
}
else
{
sq_pushnull(vm);
}
// We have a value to return on the stack
return 1;
}
/* -------------------------------------------------------------------------------------------- /* ------------------------------------------------------------------------------------------------
* Find the position of the last character that matches the specified class. * Simple forwarder to minimize templated functions with large body and reduce executable size.
*/ */
static SQInteger LastCharImpl(CSStr str) template < int (*Fn)(int), bool Neg >static SQInteger LastCharProxy(HSQUIRRELVM vm)
{ {
// See if we actually have something to search for return LastCharImpl(vm, Fn, Neg);
if(!str || *str == '\0') }
{
return -1; // Subject to change!
}
// Find the end of the string
CSStr end = std::strchr(str, '\0') - 1;
// Start iterating characters and find the first that matches
for (; end >= str; --end)
{
// Call the predicate with the current character
if (T::Fn(*end) != 0)
{
// This character passed our test
return static_cast< SQInteger >(end - str);
}
}
// Unable to locate such character
return -1;
}
/* -------------------------------------------------------------------------------------------- /* ------------------------------------------------------------------------------------------------
* Extracts and forwards the string argument to the actual implementation. * Checks if the specified character is of the specified class.
*/ */
static SQInteger LastChar(HSQUIRRELVM vm) template < int (*Fn)(int) > static bool IsCharOfType(int c)
{ {
// Attempt to retrieve the value from the stack as a string return (Fn(c) != 0);
StackStrF val(vm, 2); }
// Have we failed to retrieve the string?
if (SQ_FAILED(val.mRes))
{
return val.mRes; // Propagate the error!
}
// Perform the actual check and store the resulted value
SQInteger ret = LastCharImpl(val.mPtr);
// Have we found anything?
if (ret >= 0)
{
sq_pushinteger(vm, ret);
}
else
{
sq_pushnull(vm);
}
// We have a value to return on the stack
return 1;
}
/* --------------------------------------------------------------------------------------------
* Find the position of the last character that doesn't match the specified class.
*/
static SQInteger LastNotCharImpl(CSStr str)
{
// See if we actually have something to search for
if(!str || *str == '\0')
{
return -1; // Subject to change!
}
// Find the end of the string
CSStr end = std::strchr(str, '\0') - 1;
// Start iterating characters and find the first that matches
for (; end >= str; --end)
{
// Call the predicate with the current character
if (T::Fn(*end) == 0)
{
// This character passed our test
return static_cast< SQInteger >(end - str);
}
}
// Unable to locate such character
return -1;
}
/* --------------------------------------------------------------------------------------------
* Extracts and forwards the string argument to the actual implementation.
*/
static SQInteger LastNotChar(HSQUIRRELVM vm)
{
// Attempt to retrieve the value from the stack as a string
StackStrF val(vm, 2);
// Have we failed to retrieve the string?
if (SQ_FAILED(val.mRes))
{
return val.mRes; // Propagate the error!
}
// Perform the actual check and store the resulted value
SQInteger ret = LastNotCharImpl(val.mPtr);
// Have we found anything?
if (ret >= 0)
{
sq_pushinteger(vm, ret);
}
else
{
sq_pushnull(vm);
}
// We have a value to return on the stack
return 1;
}
};
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static bool OnlyDelimiter(CSStr str, SQChar chr) static bool OnlyDelimiter(CSStr str, SQChar chr)
@ -1309,83 +1121,83 @@ void Register_String(HSQUIRRELVM vm)
.SquirrelFunc(_SC("Lowercase"), &SqToLowercase) .SquirrelFunc(_SC("Lowercase"), &SqToLowercase)
.SquirrelFunc(_SC("Uppercase"), &SqToUppercase) .SquirrelFunc(_SC("Uppercase"), &SqToUppercase)
.SquirrelFunc(_SC("JustAlnum"), &SqJustAlphaNum) .SquirrelFunc(_SC("JustAlnum"), &SqJustAlphaNum)
.SquirrelFunc(_SC("AreAllSpace"), &StrCType< CharClassSpec< CharClass::IsSpace > >::AllChars) .SquirrelFunc(_SC("AreAllSpace"), &AllCharsProxy< std::isspace >)
.SquirrelFunc(_SC("AreAllPrint"), &StrCType< CharClassSpec< CharClass::IsPrint > >::AllChars) .SquirrelFunc(_SC("AreAllPrint"), &AllCharsProxy< std::isprint >)
.SquirrelFunc(_SC("AreAllCntrl"), &StrCType< CharClassSpec< CharClass::IsCntrl > >::AllChars) .SquirrelFunc(_SC("AreAllCntrl"), &AllCharsProxy< std::iscntrl >)
.SquirrelFunc(_SC("AreAllUpper"), &StrCType< CharClassSpec< CharClass::IsUpper > >::AllChars) .SquirrelFunc(_SC("AreAllUpper"), &AllCharsProxy< std::isupper >)
.SquirrelFunc(_SC("AreAllLower"), &StrCType< CharClassSpec< CharClass::IsLower > >::AllChars) .SquirrelFunc(_SC("AreAllLower"), &AllCharsProxy< std::islower >)
.SquirrelFunc(_SC("AreAllAlpha"), &StrCType< CharClassSpec< CharClass::IsAlpha > >::AllChars) .SquirrelFunc(_SC("AreAllAlpha"), &AllCharsProxy< std::isalpha >)
.SquirrelFunc(_SC("AreAllDigit"), &StrCType< CharClassSpec< CharClass::IsDigit > >::AllChars) .SquirrelFunc(_SC("AreAllDigit"), &AllCharsProxy< std::isdigit >)
.SquirrelFunc(_SC("AreAllPunct"), &StrCType< CharClassSpec< CharClass::IsPunct > >::AllChars) .SquirrelFunc(_SC("AreAllPunct"), &AllCharsProxy< std::ispunct >)
.SquirrelFunc(_SC("AreAllXdigit"), &StrCType< CharClassSpec< CharClass::IsXdigit > >::AllChars) .SquirrelFunc(_SC("AreAllXdigit"), &AllCharsProxy< std::isxdigit >)
.SquirrelFunc(_SC("AreAllAlnum"), &StrCType< CharClassSpec< CharClass::IsAlnum > >::AllChars) .SquirrelFunc(_SC("AreAllAlnum"), &AllCharsProxy< std::isalnum >)
.SquirrelFunc(_SC("AreAllGraph"), &StrCType< CharClassSpec< CharClass::IsGraph > >::AllChars) .SquirrelFunc(_SC("AreAllGraph"), &AllCharsProxy< std::isgraph >)
.SquirrelFunc(_SC("AreAllBlank"), &StrCType< CharClassSpec< CharClass::IsBlank > >::AllChars) .SquirrelFunc(_SC("AreAllBlank"), &AllCharsProxy< std::isblank >)
.SquirrelFunc(_SC("FirstSpace"), &StrCType< CharClassSpec< CharClass::IsSpace > >::FirstChar) .SquirrelFunc(_SC("FirstSpace"), &FirstCharProxy< std::isspace, false >)
.SquirrelFunc(_SC("FirstPrint"), &StrCType< CharClassSpec< CharClass::IsPrint > >::FirstChar) .SquirrelFunc(_SC("FirstPrint"), &FirstCharProxy< std::isprint, false >)
.SquirrelFunc(_SC("FirstCntrl"), &StrCType< CharClassSpec< CharClass::IsCntrl > >::FirstChar) .SquirrelFunc(_SC("FirstCntrl"), &FirstCharProxy< std::iscntrl, false >)
.SquirrelFunc(_SC("FirstUpper"), &StrCType< CharClassSpec< CharClass::IsUpper > >::FirstChar) .SquirrelFunc(_SC("FirstUpper"), &FirstCharProxy< std::isupper, false >)
.SquirrelFunc(_SC("FirstLower"), &StrCType< CharClassSpec< CharClass::IsLower > >::FirstChar) .SquirrelFunc(_SC("FirstLower"), &FirstCharProxy< std::islower, false >)
.SquirrelFunc(_SC("FirstAlpha"), &StrCType< CharClassSpec< CharClass::IsAlpha > >::FirstChar) .SquirrelFunc(_SC("FirstAlpha"), &FirstCharProxy< std::isalpha, false >)
.SquirrelFunc(_SC("FirstDigit"), &StrCType< CharClassSpec< CharClass::IsDigit > >::FirstChar) .SquirrelFunc(_SC("FirstDigit"), &FirstCharProxy< std::isdigit, false >)
.SquirrelFunc(_SC("FirstPunct"), &StrCType< CharClassSpec< CharClass::IsPunct > >::FirstChar) .SquirrelFunc(_SC("FirstPunct"), &FirstCharProxy< std::ispunct, false >)
.SquirrelFunc(_SC("FirstXdigit"), &StrCType< CharClassSpec< CharClass::IsXdigit > >::FirstChar) .SquirrelFunc(_SC("FirstXdigit"), &FirstCharProxy< std::isxdigit, false >)
.SquirrelFunc(_SC("FirstAlnum"), &StrCType< CharClassSpec< CharClass::IsAlnum > >::FirstChar) .SquirrelFunc(_SC("FirstAlnum"), &FirstCharProxy< std::isalnum, false >)
.SquirrelFunc(_SC("FirstGraph"), &StrCType< CharClassSpec< CharClass::IsGraph > >::FirstChar) .SquirrelFunc(_SC("FirstGraph"), &FirstCharProxy< std::isgraph, false >)
.SquirrelFunc(_SC("FirstBlank"), &StrCType< CharClassSpec< CharClass::IsBlank > >::FirstChar) .SquirrelFunc(_SC("FirstBlank"), &FirstCharProxy< std::isblank, false >)
.SquirrelFunc(_SC("FirstNotSpace"), &StrCType< CharClassSpec< CharClass::IsSpace > >::FirstNotChar) .SquirrelFunc(_SC("FirstNotSpace"), &FirstCharProxy< std::isspace, true >)
.SquirrelFunc(_SC("FirstNotPrint"), &StrCType< CharClassSpec< CharClass::IsPrint > >::FirstNotChar) .SquirrelFunc(_SC("FirstNotPrint"), &FirstCharProxy< std::isprint, true >)
.SquirrelFunc(_SC("FirstNotCntrl"), &StrCType< CharClassSpec< CharClass::IsCntrl > >::FirstNotChar) .SquirrelFunc(_SC("FirstNotCntrl"), &FirstCharProxy< std::iscntrl, true >)
.SquirrelFunc(_SC("FirstNotUpper"), &StrCType< CharClassSpec< CharClass::IsUpper > >::FirstNotChar) .SquirrelFunc(_SC("FirstNotUpper"), &FirstCharProxy< std::isupper, true >)
.SquirrelFunc(_SC("FirstNotLower"), &StrCType< CharClassSpec< CharClass::IsLower > >::FirstNotChar) .SquirrelFunc(_SC("FirstNotLower"), &FirstCharProxy< std::islower, true >)
.SquirrelFunc(_SC("FirstNotAlpha"), &StrCType< CharClassSpec< CharClass::IsAlpha > >::FirstNotChar) .SquirrelFunc(_SC("FirstNotAlpha"), &FirstCharProxy< std::isalpha, true >)
.SquirrelFunc(_SC("FirstNotDigit"), &StrCType< CharClassSpec< CharClass::IsDigit > >::FirstNotChar) .SquirrelFunc(_SC("FirstNotDigit"), &FirstCharProxy< std::isdigit, true >)
.SquirrelFunc(_SC("FirstNotPunct"), &StrCType< CharClassSpec< CharClass::IsPunct > >::FirstNotChar) .SquirrelFunc(_SC("FirstNotPunct"), &FirstCharProxy< std::ispunct, true >)
.SquirrelFunc(_SC("FirstNotXdigit"), &StrCType< CharClassSpec< CharClass::IsXdigit > >::FirstNotChar) .SquirrelFunc(_SC("FirstNotXdigit"), &FirstCharProxy< std::isxdigit, true >)
.SquirrelFunc(_SC("FirstNotAlnum"), &StrCType< CharClassSpec< CharClass::IsAlnum > >::FirstNotChar) .SquirrelFunc(_SC("FirstNotAlnum"), &FirstCharProxy< std::isalnum, true >)
.SquirrelFunc(_SC("FirstNotGraph"), &StrCType< CharClassSpec< CharClass::IsGraph > >::FirstNotChar) .SquirrelFunc(_SC("FirstNotGraph"), &FirstCharProxy< std::isgraph, true >)
.SquirrelFunc(_SC("FirstNotBlank"), &StrCType< CharClassSpec< CharClass::IsBlank > >::FirstNotChar) .SquirrelFunc(_SC("FirstNotBlank"), &FirstCharProxy< std::isblank, true >)
.SquirrelFunc(_SC("LastSpace"), &StrCType< CharClassSpec< CharClass::IsSpace > >::LastChar) .SquirrelFunc(_SC("LastSpace"), &LastCharProxy< std::isspace, false >)
.SquirrelFunc(_SC("LastPrint"), &StrCType< CharClassSpec< CharClass::IsPrint > >::LastChar) .SquirrelFunc(_SC("LastPrint"), &LastCharProxy< std::isprint, false >)
.SquirrelFunc(_SC("LastCntrl"), &StrCType< CharClassSpec< CharClass::IsCntrl > >::LastChar) .SquirrelFunc(_SC("LastCntrl"), &LastCharProxy< std::iscntrl, false >)
.SquirrelFunc(_SC("LastUpper"), &StrCType< CharClassSpec< CharClass::IsUpper > >::LastChar) .SquirrelFunc(_SC("LastUpper"), &LastCharProxy< std::isupper, false >)
.SquirrelFunc(_SC("LastLower"), &StrCType< CharClassSpec< CharClass::IsLower > >::LastChar) .SquirrelFunc(_SC("LastLower"), &LastCharProxy< std::islower, false >)
.SquirrelFunc(_SC("LastAlpha"), &StrCType< CharClassSpec< CharClass::IsAlpha > >::LastChar) .SquirrelFunc(_SC("LastAlpha"), &LastCharProxy< std::isalpha, false >)
.SquirrelFunc(_SC("LastDigit"), &StrCType< CharClassSpec< CharClass::IsDigit > >::LastChar) .SquirrelFunc(_SC("LastDigit"), &LastCharProxy< std::isdigit, false >)
.SquirrelFunc(_SC("LastPunct"), &StrCType< CharClassSpec< CharClass::IsPunct > >::LastChar) .SquirrelFunc(_SC("LastPunct"), &LastCharProxy< std::ispunct, false >)
.SquirrelFunc(_SC("LastXdigit"), &StrCType< CharClassSpec< CharClass::IsXdigit > >::LastChar) .SquirrelFunc(_SC("LastXdigit"), &LastCharProxy< std::isxdigit, false >)
.SquirrelFunc(_SC("LastAlnum"), &StrCType< CharClassSpec< CharClass::IsAlnum > >::LastChar) .SquirrelFunc(_SC("LastAlnum"), &LastCharProxy< std::isalnum, false >)
.SquirrelFunc(_SC("LastGraph"), &StrCType< CharClassSpec< CharClass::IsGraph > >::LastChar) .SquirrelFunc(_SC("LastGraph"), &LastCharProxy< std::isgraph, false >)
.SquirrelFunc(_SC("LastBlank"), &StrCType< CharClassSpec< CharClass::IsBlank > >::LastChar) .SquirrelFunc(_SC("LastBlank"), &LastCharProxy< std::isblank, false >)
.SquirrelFunc(_SC("LastNotSpace"), &StrCType< CharClassSpec< CharClass::IsSpace > >::LastNotChar) .SquirrelFunc(_SC("LastNotSpace"), &LastCharProxy< std::isspace, true >)
.SquirrelFunc(_SC("LastNotPrint"), &StrCType< CharClassSpec< CharClass::IsPrint > >::LastNotChar) .SquirrelFunc(_SC("LastNotPrint"), &LastCharProxy< std::isprint, true >)
.SquirrelFunc(_SC("LastNotCntrl"), &StrCType< CharClassSpec< CharClass::IsCntrl > >::LastNotChar) .SquirrelFunc(_SC("LastNotCntrl"), &LastCharProxy< std::iscntrl, true >)
.SquirrelFunc(_SC("LastNotUpper"), &StrCType< CharClassSpec< CharClass::IsUpper > >::LastNotChar) .SquirrelFunc(_SC("LastNotUpper"), &LastCharProxy< std::isupper, true >)
.SquirrelFunc(_SC("LastNotLower"), &StrCType< CharClassSpec< CharClass::IsLower > >::LastNotChar) .SquirrelFunc(_SC("LastNotLower"), &LastCharProxy< std::islower, true >)
.SquirrelFunc(_SC("LastNotAlpha"), &StrCType< CharClassSpec< CharClass::IsAlpha > >::LastNotChar) .SquirrelFunc(_SC("LastNotAlpha"), &LastCharProxy< std::isalpha, true >)
.SquirrelFunc(_SC("LastNotDigit"), &StrCType< CharClassSpec< CharClass::IsDigit > >::LastNotChar) .SquirrelFunc(_SC("LastNotDigit"), &LastCharProxy< std::isdigit, true >)
.SquirrelFunc(_SC("LastNotPunct"), &StrCType< CharClassSpec< CharClass::IsPunct > >::LastNotChar) .SquirrelFunc(_SC("LastNotPunct"), &LastCharProxy< std::ispunct, true >)
.SquirrelFunc(_SC("LastNotXdigit"), &StrCType< CharClassSpec< CharClass::IsXdigit > >::LastNotChar) .SquirrelFunc(_SC("LastNotXdigit"), &LastCharProxy< std::isxdigit, true >)
.SquirrelFunc(_SC("LastNotAlnum"), &StrCType< CharClassSpec< CharClass::IsAlnum > >::LastNotChar) .SquirrelFunc(_SC("LastNotAlnum"), &LastCharProxy< std::isalnum, true >)
.SquirrelFunc(_SC("LastNotGraph"), &StrCType< CharClassSpec< CharClass::IsGraph > >::LastNotChar) .SquirrelFunc(_SC("LastNotGraph"), &LastCharProxy< std::isgraph, true >)
.SquirrelFunc(_SC("LastNotBlank"), &StrCType< CharClassSpec< CharClass::IsBlank > >::LastNotChar); .SquirrelFunc(_SC("LastNotBlank"), &LastCharProxy< std::isblank, true >);
RootTable(vm).Bind(_SC("SqStr"), strns); RootTable(vm).Bind(_SC("SqStr"), strns);
RootTable(vm).SquirrelFunc(_SC("printf"), &StdPrintF); RootTable(vm).SquirrelFunc(_SC("printf"), &StdPrintF);
RootTable(vm) RootTable(vm)
.Func(_SC("IsSpace"), &CharClassSpec< CharClass::IsSpace >::Eq) .Func(_SC("IsSpace"), &IsCharOfType< std::isspace >)
.Func(_SC("IsPrint"), &CharClassSpec< CharClass::IsPrint >::Eq) .Func(_SC("IsPrint"), &IsCharOfType< std::isprint >)
.Func(_SC("IsCntrl"), &CharClassSpec< CharClass::IsCntrl >::Eq) .Func(_SC("IsCntrl"), &IsCharOfType< std::iscntrl >)
.Func(_SC("IsUpper"), &CharClassSpec< CharClass::IsUpper >::Eq) .Func(_SC("IsUpper"), &IsCharOfType< std::isupper >)
.Func(_SC("IsLower"), &CharClassSpec< CharClass::IsLower >::Eq) .Func(_SC("IsLower"), &IsCharOfType< std::islower >)
.Func(_SC("IsAlpha"), &CharClassSpec< CharClass::IsAlpha >::Eq) .Func(_SC("IsAlpha"), &IsCharOfType< std::isalpha >)
.Func(_SC("IsDigit"), &CharClassSpec< CharClass::IsDigit >::Eq) .Func(_SC("IsDigit"), &IsCharOfType< std::isdigit >)
.Func(_SC("IsPunct"), &CharClassSpec< CharClass::IsPunct >::Eq) .Func(_SC("IsPunct"), &IsCharOfType< std::ispunct >)
.Func(_SC("IsXdigit"), &CharClassSpec< CharClass::IsXdigit >::Eq) .Func(_SC("IsXdigit"), &IsCharOfType< std::isxdigit >)
.Func(_SC("IsAlnum"), &CharClassSpec< CharClass::IsAlnum >::Eq) .Func(_SC("IsAlnum"), &IsCharOfType< std::isalnum >)
.Func(_SC("IsGraph"), &CharClassSpec< CharClass::IsGraph >::Eq) .Func(_SC("IsGraph"), &IsCharOfType< std::isgraph >)
.Func(_SC("IsBlank"), &CharClassSpec< CharClass::IsBlank >::Eq) .Func(_SC("IsBlank"), &IsCharOfType< std::isblank >)
.Func(_SC("ToLower"), &tolower) .Func(_SC("ToLower"), &tolower)
.Func(_SC("ToUpper"), &toupper); .Func(_SC("ToUpper"), &toupper);
} }