Lua improvements - Mark Gossage patch #1295168

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@7476 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2005-09-20 20:57:30 +00:00
commit bf48768e04
5 changed files with 442 additions and 0 deletions

17
Lib/lua/std_except.i Normal file
View file

@ -0,0 +1,17 @@
// Typemaps used by the STL wrappers that throw exceptions.
// These typemaps are used when methods are declared with an STL exception specification, such as
// size_t at() const throw (std::out_of_range);
%{
#include <stdexcept>
%}
%include "exception.i"
%typemap(throws) std::out_of_range %{
SWIG_exception(SWIG_IndexError, $1.what()); %}
%typemap(throws) std::exception %{
SWIG_exception(SWIG_SystemError, $1.what()); %}
%typemap(throws) std::exception& %{
SWIG_exception(SWIG_SystemError, ($1)->what()); %}

122
Lib/lua/std_string.i Normal file
View file

@ -0,0 +1,122 @@
/***********************************************************************
* std_string.i
*
* std::string typemaps for LUA
*
* Author : Mark Gossage (mark@gossage.cjb.net)
************************************************************************/
%{
#include <string>
%}
/*
Only std::string and const std::string& are typemaped
they are converted to the Lua strings automatically
eg.
std::string test_value(std::string x) {
return x;
}
can be used as
s="hello world"
s2=test_value(s)
assert(s==s2)
*/
%typemap(in,checkfn="lua_isstring") std::string
%{$1 = (char*)lua_tostring(L, $input);%}
%typemap(out) std::string
%{ lua_pushstring(L,$1.c_str()); SWIG_arg++;%}
%typemap(in,checkfn="lua_isstring") const std::string& (std::string temp)
%{temp=(char*)lua_tostring(L, $input); $1=&temp;%}
%typemap(out) const std::string&
%{ lua_pushstring(L,$1->c_str()); SWIG_arg++;%}
%typemap(throws) std::string,const std::string&
%{lua_pushstring(L,$1.c_str());
SWIG_fail; %}
/*
std::string& can be wrappered, but you must inform SWIG if it is in or out
eg:
void fn(std::string& str);
Is this an in/out/inout value?
Therefore you need the usual
%apply (std::string& INOUT) {(std::string& str)};
or
%apply std::string& INOUT {std::string& str};
typemaps to tell SWIG what to do.
*/
%typemap(in) std::string &INPUT=const std::string &;
%typemap(in, numinputs=0) std::string &OUTPUT (std::string temp)
%{ $1 = &temp; %}
%typemap(argout) std::string &OUTPUT
%{ lua_pushstring(L,$1.c_str()); SWIG_arg++;%}
%typemap(in) std::string &INOUT =const std::string &;
%typemap(argout) std::string &INOUT = std::string &OUTPUT;
/*
For const std::string* and std::string* is not clear
is this a pointer or an array?
Therefore just leaving it as is
(there is some rough code below which could be used if needed
// SWIG wraps const ref's as pointer
// typemaps to deal with this and const ptrs
%typemap(in,checkfn="lua_isstring")
const std::string& INPUT(std::string temp),
const std::string* INPUT(std::string temp)
%{temp=(char*)lua_tostring(L, $input); $1=&temp;%}
%typemap(out) const std::string&, const std::string*
%{ lua_pushstring(L,$1->c_str()); SWIG_arg++;%}
// the non-const pointer version
%typemap(in) std::string *INPUT=const std::string *INPUT;
%typemap(in, numinputs=0) std::string *OUTPUT (std::string temp)
%{ $1 = &temp; %}
%typemap(argout) std::string *OUTPUT
%{ lua_pushstring(L,$1->c_str()); SWIG_arg++;%}
%typemap(in) std::string *INOUT = std::string *INPUT;
%typemap(argout) std::string *INOUT = std::string *OUTPUT;
*/
/*
A really cut down version of the string class
This provides basic mapping of lua strings <-> std::string
and little else
(the std::string has a lot of unneeded functions anyway)
*/
namespace std {
class string {
public:
string();
string(const char*);
string(const string&);
unsigned int size() const;
unsigned int length() const;
bool empty() const;
// no support for operator[]
const char* c_str()const;
const char* data()const;
// assign does not return a copy of this object
// (no point in a scripting language)
void assign(const char*);
void assign(const string&);
// no support for all the other features
// its probably better to do it in lua
};
}

133
Lib/lua/std_vector.i Normal file
View file

@ -0,0 +1,133 @@
/***********************************************************************
* std_vector.i
*
* std::vector typemaps for LUA
*
* Author : Mark Gossage (mark@gossage.cjb.net)
************************************************************************/
%{
#include <vector>
%}
%include <std_except.i> // the general exepctions
/*
A really cut down version of the vector class.
Note: this does not match the true std::vector class
but instead is an approximate, so that SWIG knows how to wrapper it.
(Eg, all access is by value, not ref, as SWIG turns refs to pointers)
And no support for iterators & insert/erase
It would be useful to have a vector<->Lua table conversion routine
*/
namespace std {
template<class T>
class vector {
public:
vector();
vector(unsigned int);
vector(const vector&);
vector(unsigned int,T);
unsigned int size() const;
unsigned int max_size() const;
bool empty() const;
void clear();
void push_back(T val);
void pop_back();
T front()const; // only read front & back
T back()const; // not write to them
// operator [] given later:
%extend // this is a extra bit of SWIG code
{
// [] is replaced by __getitem__ & __setitem__
// simply throws a string, which causes a lua error
T __getitem__(unsigned int idx) throw (std::out_of_range)
{
if (idx>=self->size())
throw std::out_of_range("in vector::__getitem__()");
return (*self)[idx];
}
void __setitem__(unsigned int idx,T val) throw (std::out_of_range)
{
if (idx>=self->size())
throw std::out_of_range("in vector::__setitem__()");
(*self)[idx]=val;
}
};
};
}
/*
Vector<->LuaTable fns
These look a bit like the array<->LuaTable fns
but are templated, not %defined
(you must have template support for STL)
*/
/*
%{
// reads a table into a vector of numbers
// lua numbers will be cast into the type required (rounding may occur)
// return 0 if non numbers found in the table
// returns new'ed ptr if ok
template<class T>
std::vector<T>* SWIG_read_number_vector(lua_State* L,int index)
{
int i=0;
std::vector<T>* vec=new std::vector<T>();
while(1)
{
lua_rawgeti(L,index,i+1);
if (!lua_isnil(L,-1))
{
lua_pop(L,1);
break; // finished
}
if (!lua_isnumber(L,-1))
{
lua_pop(L,1);
delete vec;
return 0; // error
}
vec->push_back((T)lua_tonumber(L,-1));
lua_pop(L,1);
++i;
}
return vec; // ok
}
// writes a vector of numbers out as a lua table
template<class T>
int SWIG_write_number_vector(lua_State* L,std::vector<T> *vec)
{
lua_newtable(L);
for(int i=0;i<vec->size();++i)
{
lua_pushnumber(L,(double)((*vec)[i]));
lua_rawseti(L,-2,i+1);// -1 is the number, -2 is the table
}
}
%}
// then the typemaps
%define SWIG_TYPEMAP_NUM_VECTOR(T)
// in
%typemap(in) std::vector<T> *INPUT
%{ $1 = SWIG_read_number_vector<T>(L,$input);
if (!$1) SWIG_fail;%}
%typemap(freearg) std::vector<T> *INPUT
%{ delete $1;%}
// out
%typemap(argout) std::vector<T> *OUTPUT
%{ SWIG_write_number_vector(L,$1); SWIG_arg++; %}
%enddef
*/