lua-users home
lua-l archive

Re: String equality?

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


continuing an old thread...
I don't remember if anybody suggested solution for Chris question that was 
stable on (hypothetical) memory compacting GC and at the same time allowed 
for easy pointer comparison; but this is what i've just tried:
/*--------- string equality helper ------------*/
static int myStatKey;
static void regString (lua_State *L, const char *s) {
	lua_pushlightuserdata (L, myStatKey);
	lua_gettable (L, LUA_REGISTRYINDEX);
	if (lua_isnil (L, -1)) {
		lua_pop (L, 1);
		lua_newtable (L);
		lua_pushlightuserdata (L, myStatKey);
		lua_pushvalue (L, -2);
		lua_settable (L, LUA_REGISTRYINDEX);
	}
	lua_pushstring (L, s);
	lua_pushlightuserdata (L, s);
	lua_settable (L, -3);
}
static const char *toStringReg (lua_State *L, int n) {
	const char *r = NULL;
	lua_pushlightuserdata (L, myStatKey);
	lua_gettable (L, LUA_REGISTRYINDEX);
	if (lua_isnil (L, -1)) {
		lua_pop (L, 1);
		return NULL;
	}
	lua_pushvalue (L, n);
	lua_gettable (L, -2);
	r = lua_touserdata (L, -1);
	lua_pop (L, 1);
	return r;
}
/*------ end --------*/
the static int variable is used as a key in the registry, to avoid collisions. 
to use it, just register any constant string you'd like to use (at module 
initialization time):
	regString (L, "foo");
	regString (L, "bar");
and, in your __index() metamethod (or anywhere you'd like to test a Lua 
string against several C strings), first convert it to the registered 
pointer:
const char *k = *toStringReg (L, n); /* n is a stack position */
if (k == "foo") {
	do_something ();
} else if (k == "bar") {
	do_someelse ():
} else {
	not_found ();
}
of course, this depends on the compiler optimizing equal constant strings to 
the same location in memory.
a little variation would be to store small integers (from an enum type) 
instead of the const char pointers. this would make possible to use 
switch(getreg(L,n)) {.....}
-- 
Javier

Attachment: pgpBYSdUL72pK.pgp
Description: PGP signature


AltStyle によって変換されたページ (->オリジナル) /