ug4
lua_parsing.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2015: G-CSC, Goethe University Frankfurt
3  * Author: Martin Rupp
4  *
5  * This file is part of UG4.
6  *
7  * UG4 is free software: you can redistribute it and/or modify it under the
8  * terms of the GNU Lesser General Public License version 3 (as published by the
9  * Free Software Foundation) with the following additional attribution
10  * requirements (according to LGPL/GPL v3 §7):
11  *
12  * (1) The following notice must be displayed in the Appropriate Legal Notices
13  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14  *
15  * (2) The following notice must be displayed at a prominent place in the
16  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17  *
18  * (3) The following bibliography is recommended for citation and must be
19  * preserved in all covered files:
20  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21  * parallel geometric multigrid solver on hierarchically distributed grids.
22  * Computing and visualization in science 16, 4 (2013), 151-164"
23  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24  * flexible software system for simulating pde based models on high performance
25  * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26  *
27  * This program is distributed in the hope that it will be useful,
28  * but WITHOUT ANY WARRANTY; without even the implied warranty of
29  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30  * GNU Lesser General Public License for more details.
31  */
32 
33 #ifndef LUA_PARSING_H_
34 #define LUA_PARSING_H_
35 
36 #ifdef USE_LUAJIT
37 #include <lua.h>
38 #else
39 #include "externals/lua/lua.h"
40 #endif
41 
42 #include "bindings_lua.h"
45 
46 namespace ug{
47 namespace bridge{
48 namespace lua{
49 
50 template <typename T>
51 struct LuaParsing;
52 
53 template <>
54 struct LuaParsing<bool>{
55  static bool check(lua_State* L, int index){
56  return lua_isboolean(L, index);
57  }
58  static bool get(lua_State* L, int index){
59  return lua_toboolean(L, index);
60  }
61  static void push(lua_State* L, bool data){
62  lua_pushboolean(L, (data ? 1 : 0));
63  }
64 };
65 
66 template <>
67 struct LuaParsing<int>{
68  static bool check(lua_State* L, int index){
69  return lua_isnumber(L, index);
70  }
71  static int get(lua_State* L, int index){
72  return (int)lua_tointeger(L, index);
73  }
74  static void push(lua_State* L, int data){
75  lua_pushnumber(L, data);
76  }
77 };
78 
79 template <>
80 struct LuaParsing<size_t>{
81  static bool check(lua_State* L, int index){
82  return lua_isnumber(L, index);
83  }
84  static size_t get(lua_State* L, int index){
85  return lua_tointeger(L, index);
86  }
87  static void push(lua_State* L, size_t data){
88  lua_pushnumber(L, (lua_Number)data);
89  }
90 };
91 
92 template <>
93 struct LuaParsing<float>{
94  static bool check(lua_State* L, int index){
95  return lua_isnumber(L, index);
96  }
97  static float get(lua_State* L, int index){
98  return (float)lua_tonumber(L, index);
99  }
100  static void push(lua_State* L, float data){
101  lua_pushnumber(L, data);
102  }
103 };
104 
105 template <>
106 struct LuaParsing<double>{
107  static bool check(lua_State* L, int index){
108  return lua_isnumber(L, index);
109  }
110  static double get(lua_State* L, int index){
111  return lua_tonumber(L, index);
112  }
113  static void push(lua_State* L, double data){
114  lua_pushnumber(L, data);
115  }
116 };
117 
118 template <>
119 struct LuaParsing<const char*>{
120  static bool check(lua_State* L, int index){
121  return lua_isstring(L, index);
122  }
123  static const char* get(lua_State* L, int index){
124  return lua_tostring(L, index);
125  }
126  static void push(lua_State* L, const char* data){
127  lua_pushstring(L, data);
128  }
129 };
130 
131 template <>
132 struct LuaParsing<std::string>{
133  static bool check(lua_State* L, int index){
134  return lua_isstring(L, index);
135  }
136  static std::string get(lua_State* L, int index){
137  return std::string(lua_tostring(L, index));
138  }
139  static void push(lua_State* L, std::string data){
140  lua_pushstring(L, data.c_str());
141  }
142 };
143 
144 template <>
145 struct LuaParsing<const std::string&>{
146  static bool check(lua_State* L, int index){
147  return lua_isstring(L, index);
148  }
149  static void push(lua_State* L, const std::string& data){
150  lua_pushstring(L, data.c_str());
151  }
152 };
153 
154 #ifdef UG_FOR_LUA
155 template <>
156 struct LuaParsing<LuaFunctionHandle>{
157  static bool check(lua_State* L, int index){
158  return lua_isfunction(L, index);
159  }
160  static LuaFunctionHandle get(lua_State* L, int index){
161  LuaFunctionHandle tmp;
162  lua_pushvalue(L, index);
163  tmp.ref = luaL_ref(L, LUA_REGISTRYINDEX);
164  return tmp;
165  }
166  static void push(lua_State* L, LuaFunctionHandle data){
167  UG_THROW("Return value of type LuaFunctionHandle not implemented.");
168  }
169 };
170 
171 template <>
172 struct LuaParsing<LuaTableHandle>{
173  static bool check(lua_State* L, int index){
174  return lua_istable(L, index);
175  }
176  static LuaTableHandle get(lua_State* L, int index){
177  LuaTableHandle tmp(L, index);
178  untested();
179  return tmp;
180  }
181  static void push(lua_State* L, LuaTableHandle data){
182  UG_THROW("Return value of type LuaTableHandle not implemented.");
183  }
184 };
185 #endif
186 
187 template <>
188 struct LuaParsing<void*>{
189  static bool checkAndGet(std::pair<void*, const ClassNameNode*>& res,
190  lua_State* L, int index, const char* baseClassName){
191  if(!lua_isuserdata(L, index)) return false;
192 
193  UserDataWrapper* udata =
194  reinterpret_cast<UserDataWrapper*>(lua_touserdata(L, index));
195 
196  if(udata->is_const()) return false;
197 
198  // extract the pointer to the object.
199  // udata is either a RawUserData or a SmartUserDataWrapper
200  void* obj = NULL;
201  if(udata->is_raw_ptr())
202  obj = static_cast<RawUserDataWrapper*>(udata)->obj;
204  obj = static_cast<SmartUserDataWrapper*>(udata)->smartPtr.get();
205  else return false;
206 
207  // get the object and its metatable. Make sure that obj can be cast to
208  // the type that is expected by the paramsTemplate.
209  if(lua_getmetatable(L, index) == 0) return false;
210 
211  lua_pushstring(L, "class_name_node");
212  lua_rawget(L, -2);
213  const ClassNameNode* classNameNode = (const ClassNameNode*) lua_touserdata(L, -1);
214  lua_pop(L, 2);
215 
216  if(!classNameNode) return false;
217  if(classNameNode->empty()) return false;
218  if(!ClassNameTreeContains(*classNameNode, baseClassName)) return false;
219 
220  res.first = obj;
221  res.second = classNameNode;
222 
223  return true;
224  }
225 
226  static void push(lua_State* L, void* data, const char* className){
227  CreateNewUserData(L, data, className, NULL, false);
228  }
229 };
230 
231 template <>
232 struct LuaParsing<const void*>{
233  static bool checkAndGet(std::pair<const void*, const ClassNameNode*>& res,
234  lua_State* L, int index, const char* baseClassName){
235  if(!lua_isuserdata(L, index)) return false;
236 
237  UserDataWrapper* udata =
238  reinterpret_cast<UserDataWrapper*>(lua_touserdata(L, index));
239 
240  // extract the pointer to the object.
241  // udata is either a RawUserData or a SmartUserDataWrapper
242  const void* obj = NULL;
243 
244  if(udata->is_raw_ptr())
245  obj = static_cast<RawUserDataWrapper*>(udata)->obj;
247  // we have to distinguish between const and non-const smart pointers.
248  if(udata->is_const())
249  obj = static_cast<ConstSmartUserDataWrapper*>(udata)->smartPtr.get();
250  else
251  obj = static_cast<SmartUserDataWrapper*>(udata)->smartPtr.get();
252  }
253  else return false;
254 
255  // get the object and its metatable. Make sure that obj can be cast to
256  // the type that is expected by the paramsTemplate.
257  if(lua_getmetatable(L, index) == 0) return false;
258 
259  lua_pushstring(L, "class_name_node");
260  lua_rawget(L, -2);
261  const ClassNameNode* classNameNode = (const ClassNameNode*) lua_touserdata(L, -1);
262  lua_pop(L, 2);
263 
264  if(!classNameNode) return false;
265  if(classNameNode->empty()) return false;
266  if(!ClassNameTreeContains(*classNameNode, baseClassName)) return false;
267 
268  res.first = obj;
269  res.second = classNameNode;
270 
271  return true;
272  }
273 
274  static void push(lua_State* L, const void* data, const char* className){
275  // we're removing const with a cast. However, it was made sure that
276  // obj is treated as a const value.
277  CreateNewUserData(L, (void*)data, className, NULL, true);
278  }
279 };
280 
281 template <>
282 struct LuaParsing<SmartPtr<void> >{
283  static bool checkAndGet(std::pair<SmartPtr<void>, const ClassNameNode*>& res,
284  lua_State* L, int index, const char* baseClassName){
285  if(!lua_isuserdata(L, index)) return false;
286 
287  UserDataWrapper* udata =
288  reinterpret_cast<UserDataWrapper*>(lua_touserdata(L, index));
289 
290  if(!udata->is_smart_ptr()) return false;
291  if(udata->is_const()) return false;
292 
293  SmartPtr<void>& obj = ((SmartUserDataWrapper*)lua_touserdata(L, index))->smartPtr;
294 
295  if(lua_getmetatable(L, index) == 0) return false;
296  lua_pushstring(L, "class_name_node");
297  lua_rawget(L, -2);
298  const ClassNameNode* classNameNode = (const ClassNameNode*) lua_touserdata(L, -1);
299  lua_pop(L, 2);
300 
301  if(!classNameNode) return false;
302  if(classNameNode->empty()) return false;
303  if(!ClassNameTreeContains(*classNameNode, baseClassName)) return false;
304 
305  res.first = obj;
306  res.second = classNameNode;
307 
308  return true;
309  }
310 
311  static void push(lua_State* L, SmartPtr<void> data, const char* className){
312  CreateNewUserData(L, data, className);
313  }
314 };
315 
316 template <>
317 struct LuaParsing<ConstSmartPtr<void> >{
318  static bool checkAndGet(std::pair<ConstSmartPtr<void>, const ClassNameNode*>& res,
319  lua_State* L, int index, const char* baseClassName){
320  if(!lua_isuserdata(L, index)) return false;
321 
322  UserDataWrapper* udata =
323  reinterpret_cast<UserDataWrapper*>(lua_touserdata(L, index));
324 
325  if(!udata->is_smart_ptr()) return false;
326 
328  if(((UserDataWrapper*)lua_touserdata(L, index))->is_const())
329  obj = ((ConstSmartUserDataWrapper*)lua_touserdata(L, index))->smartPtr;
330  else
331  obj = ((SmartUserDataWrapper*)lua_touserdata(L, index))->smartPtr;
332 
333  if(lua_getmetatable(L, index) == 0) return false;
334  lua_pushstring(L, "class_name_node");
335  lua_rawget(L, -2);
336  const ClassNameNode* classNameNode = (const ClassNameNode*) lua_touserdata(L, -1);
337  lua_pop(L, 2);
338 
339  if(!classNameNode) return false;
340  if(classNameNode->empty()) return false;
341  if(!ClassNameTreeContains(*classNameNode, baseClassName)) return false;
342 
343  res.first = obj;
344  res.second = classNameNode;
345 
346  return true;
347  }
348 
349  static void push(lua_State* L, ConstSmartPtr<void> data, const char* className){
350  CreateNewUserData(L, data, className);
351  }
352 };
353 
354 
355 }
356 }
357 }
358 #endif /* LUA_PARSING_H_ */
359 
Definition: smart_pointer.h:650
const void * get() const
Definition: smart_pointer.h:789
Definition: smart_pointer.h:296
Definition: smart_pointer.h:525
void * get()
Definition: smart_pointer.h:625
Definition: smart_pointer.h:108
Handle for a lua reference.
Definition: lua_function_handle.h:40
int ref
Definition: lua_function_handle.h:42
node for class names
Definition: class_name_provider.h:65
bool empty() const
returns if a name has been set
Definition: class_name_provider.h:80
bool ClassNameTreeContains(const ClassNameNode &node, const std::string &name)
returns if a name is contained in the name tree at node or in base classes
Definition: class_name_provider.cpp:104
#define UG_THROW(msg)
Definition: error.h:57
#define untested()
Definition: lua_table_handle.cpp:15
struct lua_State lua_State
Definition: lua_table_handle.h:40
SM_edge_weight_map< typename T::value_type, ug::BidirectionalMatrix< T > > get(edge_weight_t, ug::BidirectionalMatrix< T > const &g)
Definition: bidirectional_boost.h:157
Definition: smart_pointer.h:814
const bool IMLPICIT_SMART_PTR_TO_PTR_CONVERSION
Definition: bindings_lua.cpp:129
SmartUserDataWrapper * CreateNewUserData(lua_State *L, const SmartPtr< void > &ptr, const char *metatableName)
creates a new UserDataWrapper and associates it with ptr in luas registry
Definition: bindings_lua.cpp:174
the ug namespace
Definition: bindings_lua.h:78
ConstSmartPtr< void > smartPtr
Definition: bindings_lua.h:79
static void push(lua_State *L, ConstSmartPtr< void > data, const char *className)
Definition: lua_parsing.h:349
static bool checkAndGet(std::pair< ConstSmartPtr< void >, const ClassNameNode * > &res, lua_State *L, int index, const char *baseClassName)
Definition: lua_parsing.h:318
static bool checkAndGet(std::pair< SmartPtr< void >, const ClassNameNode * > &res, lua_State *L, int index, const char *baseClassName)
Definition: lua_parsing.h:283
static void push(lua_State *L, SmartPtr< void > data, const char *className)
Definition: lua_parsing.h:311
static bool check(lua_State *L, int index)
Definition: lua_parsing.h:55
static bool get(lua_State *L, int index)
Definition: lua_parsing.h:58
static void push(lua_State *L, bool data)
Definition: lua_parsing.h:61
static const char * get(lua_State *L, int index)
Definition: lua_parsing.h:123
static void push(lua_State *L, const char *data)
Definition: lua_parsing.h:126
static bool check(lua_State *L, int index)
Definition: lua_parsing.h:120
static void push(lua_State *L, const std::string &data)
Definition: lua_parsing.h:149
static bool check(lua_State *L, int index)
Definition: lua_parsing.h:146
static bool checkAndGet(std::pair< const void *, const ClassNameNode * > &res, lua_State *L, int index, const char *baseClassName)
Definition: lua_parsing.h:233
static void push(lua_State *L, const void *data, const char *className)
Definition: lua_parsing.h:274
static bool check(lua_State *L, int index)
Definition: lua_parsing.h:107
static void push(lua_State *L, double data)
Definition: lua_parsing.h:113
static double get(lua_State *L, int index)
Definition: lua_parsing.h:110
static void push(lua_State *L, float data)
Definition: lua_parsing.h:100
static bool check(lua_State *L, int index)
Definition: lua_parsing.h:94
static float get(lua_State *L, int index)
Definition: lua_parsing.h:97
static bool check(lua_State *L, int index)
Definition: lua_parsing.h:68
static int get(lua_State *L, int index)
Definition: lua_parsing.h:71
static void push(lua_State *L, int data)
Definition: lua_parsing.h:74
static void push(lua_State *L, size_t data)
Definition: lua_parsing.h:87
static size_t get(lua_State *L, int index)
Definition: lua_parsing.h:84
static bool check(lua_State *L, int index)
Definition: lua_parsing.h:81
static std::string get(lua_State *L, int index)
Definition: lua_parsing.h:136
static void push(lua_State *L, std::string data)
Definition: lua_parsing.h:139
static bool check(lua_State *L, int index)
Definition: lua_parsing.h:133
static bool checkAndGet(std::pair< void *, const ClassNameNode * > &res, lua_State *L, int index, const char *baseClassName)
Definition: lua_parsing.h:189
static void push(lua_State *L, void *data, const char *className)
Definition: lua_parsing.h:226
Definition: lua_parsing.h:51
Definition: bindings_lua.h:83
void * obj
Definition: bindings_lua.h:84
Definition: bindings_lua.h:73
SmartPtr< void > smartPtr
Definition: bindings_lua.h:74
Definition: bindings_lua.h:64
bool is_const()
Definition: bindings_lua.h:67
bool is_raw_ptr()
Definition: bindings_lua.h:68
bool is_smart_ptr()
Definition: bindings_lua.h:69