Added visitors for converting config attributes.

(Partial fix for bug #16363.)

This brings the profile footprint of pushing units to Lua tables from
15% to 5%.
This commit is contained in:
Guillaume Melquiond 2010-08-06 16:31:01 +00:00
parent ac99cc5f9d
commit 419cf84a9d
3 changed files with 49 additions and 7 deletions

View file

@ -113,15 +113,28 @@ double config::attribute_value::to_double(double def) const
return def;
}
struct config_attribute_str_visitor : boost::static_visitor<std::string>
{
std::string operator()(boost::blank const &) const
{ return std::string(); }
std::string operator()(bool b) const
{
static std::string s_yes("yes"), s_no("no");
return b ? s_yes : s_no;
}
std::string operator()(int i) const
{ return str_cast(i); }
std::string operator()(double d) const
{ return str_cast(d); }
std::string operator()(std::string const &s) const
{ return s; }
std::string operator()(t_string const &s) const
{ return s.str(); }
};
std::string config::attribute_value::str() const
{
static std::string s_yes("yes"), s_no("no");
if (const std::string *p = boost::get<const std::string>(&value)) return *p;
if (const t_string *p = boost::get<const t_string>(&value)) return p->str();
if (const bool *p = boost::get<const bool>(&value)) return *p ? s_yes : s_no;
if (const int *p = boost::get<const int>(&value)) return str_cast(*p);
if (const double *p = boost::get<const double>(&value)) return str_cast(*p);
return std::string();
return boost::apply_visitor(config_attribute_str_visitor(), value);
}
t_string config::attribute_value::t_str() const

View file

@ -42,6 +42,7 @@
typedef std::map<std::string, t_string> string_map;
class config;
struct lua_State;
bool operator==(const config &, const config &);
inline bool operator!=(const config &a, const config &b) { return !operator==(a, b); }
@ -199,6 +200,7 @@ public:
{ return !operator==(other); }
friend std::ostream& operator<<(std::ostream &os, const attribute_value &v);
friend void luaW_pushscalar(lua_State *, const attribute_value &);
};
typedef std::map<std::string, attribute_value> attribute_map;

View file

@ -28,6 +28,7 @@
#include <cassert>
#include <cstring>
#include <boost/variant.hpp>
#include "scripting/lua.hpp"
#include "scripting/lua_api.hpp"
@ -138,6 +139,32 @@ static void luaW_pushtstring(lua_State *L, t_string const &v)
lua_setmetatable(L, -2);
}
struct luaW_pushscalar_visitor : boost::static_visitor<>
{
lua_State *L;
luaW_pushscalar_visitor(lua_State *l): L(l) {}
void operator()(boost::blank const &) const
{ lua_pushnil(L); }
void operator()(bool b) const
{ lua_pushboolean(L, b); }
void operator()(int i) const
{ lua_pushinteger(L, i); }
void operator()(double d) const
{ lua_pushnumber(L, d); }
void operator()(std::string const &s) const
{ lua_pushstring(L, s.c_str()); }
void operator()(t_string const &s) const
{ luaW_pushtstring(L, s); }
};
/**
* Converts a string into a Lua object pushed at the top of the stack.
*/
void luaW_pushscalar(lua_State *L, config::attribute_value const &v)
{
boost::apply_visitor(luaW_pushscalar_visitor(L), v.value);
}
/**
* Converts a string into a Lua object pushed at the top of the stack.
* Boolean ("yes"/"no") and numbers are detected and typed accordingly.