Geogram  Version 1.9.1
A programming library of geometric algorithms
lua_wrap.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2000-2022 Inria
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  * * Neither the name of the ALICE Project-Team nor the names of its
14  * contributors may be used to endorse or promote products derived from this
15  * software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  *
29  * Contact: Bruno Levy
30  *
31  * https://www.inria.fr/fr/bruno-levy
32  *
33  * Inria,
34  * Domaine de Voluceau,
35  * 78150 Le Chesnay - Rocquencourt
36  * FRANCE
37  *
38  */
39 
40 #ifndef GEOGRAM_LUA_LUA_WRAP
41 
42 #include <geogram/basic/common.h>
43 #include <geogram/basic/assert.h>
44 #include <geogram/basic/numeric.h>
45 #include <geogram/basic/string.h>
46 #include <geogram/basic/memory.h>
47 
48 extern "C" {
49 #include <geogram/third_party/lua/lua.h>
50 #include <geogram/third_party/lua/lauxlib.h>
51 #include <geogram/third_party/lua/lualib.h>
52 }
53 
54 #ifdef GEO_COMPILER_MSVC
55 #pragma warning( push )
56 #pragma warning( disable: 4702 )
57 #endif
58 
64 namespace GEO {
65 
70  typedef int (*lua_test_func)(lua_State* L, int idx);
71 
72 
84  inline int my_lua_isboolean(lua_State* L, int idx) {
85  return lua_isboolean(L,idx);
86  }
87 
99  inline int my_lua_islightuserdata(lua_State* L, int idx) {
100  return lua_islightuserdata(L,idx);
101  }
102 
112  inline int my_lua_ispositiveinteger(lua_State* L, int idx) {
113  if(!lua_isinteger(L,idx)) {
114  return 0;
115  }
116  lua_Integer x = lua_tointeger(L,idx);
117  return (x > 0) ? 1 : 0;
118  }
119 
128  inline void lua_set_error(lua_State* L, const char* error) {
129  lua_pushstring(L, error);
130  lua_setfield(L,LUA_REGISTRYINDEX,"last_geogram_error");
131  }
132 
141  inline void lua_set_error(lua_State* L, const std::string& error) {
142  lua_set_error(L,error.c_str());
143  }
144 
149  inline void lua_clear_error(lua_State* L) {
150  lua_pushnil(L);
151  lua_setfield(L,LUA_REGISTRYINDEX,"last_geogram_error");
152  }
153 
159  inline bool lua_has_error(lua_State* L) {
160  lua_getfield(L,LUA_REGISTRYINDEX,"last_geogram_error");
161  bool result = !lua_isnil(L,-1);
162  lua_pop(L,1);
163  return result;
164  }
165 
178  inline bool lua_check_type(lua_State* L, int idx, lua_test_func test) {
179  if(!test(L,idx)) {
180  std::string error = std::string("Argument ") +
181  String::to_string(idx) + ": wrong argument type (" +
182  "got " + lua_typename(L,lua_type(L,idx)) + ")";
183  lua_set_error(L, error.c_str());
184  return false;
185  }
186  return true;
187  }
188 
201  inline bool lua_check_nb_args(lua_State* L, int expected_nb_args) {
202  if(lua_gettop(L) != expected_nb_args) {
203  std::string error =
204  "Expected " + String::to_string(expected_nb_args)
205  + " arg(s), got " + String::to_string(lua_gettop(L));
206  lua_set_error(L,error.c_str());
207  return false;
208  }
209  return true;
210  }
211 
225  inline int lua_notify_last_error(lua_State* L) {
226  std::string error;
227  lua_getfield(L,LUA_REGISTRYINDEX,"last_geogram_error");
228  if(lua_isstring(L,-1)) {
229  error += lua_tostring(L,-1);
230  }
231  lua_pop(L,1);
232  lua_clear_error(L);
233  return luaL_error(L,error.c_str());
234  }
235 
236  /**********************************************************************/
237 
243  template <class T> class lua_to {
244  public:
257  lua_to(lua_State* L, int idx) {
258  geo_argused(L);
259  geo_argused(idx);
261  }
262 
275  static bool can_convert(lua_State* L, int idx) {
276  geo_argused(L);
277  geo_argused(idx);
279  }
280 
285  operator T() const {
287  }
288  protected:
289  T x_;
290  };
291 
295  template<> class lua_to<int> {
296  public:
297  lua_to(lua_State* L, int idx) {
298  x_ = int(lua_tointeger(L,idx));
299  }
300  static bool can_convert(lua_State* L, int idx) {
301  return lua_check_type(L, idx, lua_isinteger);
302  }
303  operator int() const {
304  return x_;
305  }
306  private:
307  int x_;
308  };
309 
313  template<> class lua_to<Numeric::uint32> {
314  public:
315  lua_to(lua_State* L, int idx) {
316  x_ = Numeric::uint32(lua_tointeger(L,idx));
317  }
318  static bool can_convert(lua_State* L, int idx) {
320  }
321  operator Numeric::uint32() const {
322  return x_;
323  }
324  private:
325  Numeric::uint32 x_;
326  };
327 
331  template<> class lua_to<Numeric::uint64> {
332  public:
333  lua_to(lua_State* L, int idx) {
334  x_ = Numeric::uint64(lua_tointeger(L,idx));
335  }
336  static bool can_convert(lua_State* L, int idx) {
338  }
339  operator Numeric::uint64() const {
340  return x_;
341  }
342  private:
343  Numeric::uint64 x_;
344  };
345 
346 
350  template<> class lua_to<Numeric::int64> {
351  public:
352  lua_to(lua_State* L, int idx) {
353  x_ = Numeric::int64(lua_tointeger(L,idx));
354  }
355  static bool can_convert(lua_State* L, int idx) {
356  return lua_check_type(L, idx, lua_isinteger);
357  }
358  operator Numeric::int64() const {
359  return x_;
360  }
361  private:
362  Numeric::int64 x_;
363  };
364 
368  template<> class lua_to<float> {
369  public:
370  lua_to(lua_State* L, int idx) {
371  x_ = float(lua_tonumber(L,idx));
372  }
373  static bool can_convert(lua_State* L, int idx) {
374  return lua_check_type(L, idx, lua_isnumber);
375  }
376  operator float() const {
377  return x_;
378  }
379  private:
380  float x_;
381  };
382 
386  template<> class lua_to<double> {
387  public:
388  lua_to(lua_State* L, int idx) {
389  x_ = double(lua_tonumber(L,idx));
390  }
391  static bool can_convert(lua_State* L, int idx) {
392  return lua_check_type(L, idx, lua_isnumber);
393  }
394  operator double() const {
395  return x_;
396  }
397  private:
398  double x_;
399  };
400 
404  template<> class lua_to<bool> {
405  public:
406  lua_to(lua_State* L, int idx) {
407  x_ = (lua_toboolean(L,idx) != 0);
408  }
409  static bool can_convert(lua_State* L, int idx) {
410  return lua_check_type(L, idx, my_lua_isboolean);
411  }
412  operator bool() const {
413  return x_;
414  }
415  private:
416  bool x_;
417  };
418 
422  template<> class lua_to<const char*> {
423  public:
424  lua_to(lua_State* L, int idx) {
425  x_ = lua_tostring(L,idx);
426  }
427  static bool can_convert(lua_State* L, int idx) {
428  return lua_check_type(L, idx, lua_isstring);
429  }
430  operator const char*() const {
431  return x_;
432  }
433  private:
434  const char* x_;
435  };
436 
440  template<> class lua_to<const std::string&> {
441  public:
442  lua_to(lua_State* L, int idx) {
443  x_ = lua_tostring(L,idx);
444  }
445  static bool can_convert(lua_State* L, int idx) {
446  return lua_check_type(L, idx, lua_isstring);
447  }
448  operator const std::string&() const {
449  return x_;
450  }
451  private:
452  std::string x_;
453  };
454 
458  template<> class lua_to<std::string> {
459  public:
460  lua_to(lua_State* L, int idx) {
461  x_ = lua_tostring(L,idx);
462  }
463  static bool can_convert(lua_State* L, int idx) {
464  return lua_check_type(L, idx, lua_isstring);
465  }
466  operator std::string() const {
467  return x_;
468  }
469  private:
470  std::string x_;
471  };
472 
473  /**********************************************************************/
474 
484  template<class T> inline void lua_push(lua_State* L, T x) {
485  geo_argused(L);
486  geo_argused(x);
488  }
489 
493  template<> inline void lua_push(lua_State* L, int x) {
494  lua_pushinteger(L,lua_Integer(x));
495  }
496 
497 
501  template<> inline void lua_push(lua_State* L, Numeric::uint32 x) {
502  lua_pushinteger(L,lua_Integer(x));
503  }
504 
508  template<> inline void lua_push(lua_State* L, Numeric::uint64 x) {
509  lua_pushinteger(L,lua_Integer(x));
510  }
511 
515  template<> inline void lua_push(lua_State* L, Numeric::int64 x) {
516  lua_pushinteger(L,lua_Integer(x));
517  }
518 
522  template<> inline void lua_push(lua_State* L, float x) {
523  lua_pushnumber(L,lua_Number(x));
524  }
525 
529  template<> inline void lua_push(lua_State* L, double x) {
530  lua_pushnumber(L,lua_Number(x));
531  }
532 
536  template<> inline void lua_push(lua_State* L, bool x) {
537  lua_pushboolean(L,x?1:0);
538  }
539 
543  template<> inline void lua_push(lua_State* L, const char* x) {
544  lua_pushstring(L,x);
545  }
546 
550  template<> inline void lua_push(lua_State* L, const std::string& x) {
551  lua_pushstring(L,x.c_str());
552  }
553 
557  template<> inline void lua_push(lua_State* L, std::string x) {
558  lua_pushstring(L,x.c_str());
559  }
560 
566  template<class T> inline void lua_push(
567  lua_State* L, const std::vector<T>& x
568  ) {
569  lua_newtable(L);
570  for(size_t i=0; i<x.size(); ++i) {
571  lua_push(L,x[i]);
572  lua_seti(L,-2,lua_Integer(i+1));
573  }
574  }
575 
586 #define LUA_DECLAREENUMTYPE(T) \
587  template<> inline void lua_push(lua_State* L, T x) { \
588  lua_push(L, int(x)); \
589  } \
590  \
591  template<> class lua_to<T> : public GEO::lua_to<int> { \
592  public: \
593  lua_to(lua_State* L, int idx) : lua_to<int>(L,idx) { \
594  } \
595  operator T() const { \
596  return T(lua_to<int>::operator int()); \
597  } \
598  }
599 
600  /**********************************************************************/
601 
609  template <class R> inline int lua_wrap(lua_State* L, R (*fptr)(void)) {
610  if(!lua_check_nb_args(L,0)) {
611  return lua_notify_last_error(L);
612  }
613  R retval = fptr();
614  lua_push(L,retval);
615  return 1;
616  }
617 
625  template <class R, class T1> inline int lua_wrap(
626  lua_State* L, R (*fptr)(T1)
627  ) {
628  if(
629  !lua_check_nb_args(L,1) ||
631  ) {
632  return lua_notify_last_error(L);
633  }
634  R retval = fptr(
635  lua_to<T1>(L,1)
636  );
637  lua_push(L,retval);
638  return 1;
639  }
640 
648  template <class R, class T1, class T2> inline int lua_wrap(
649  lua_State* L, R (*fptr)(T1,T2)
650  ) {
651  if(
652  !lua_check_nb_args(L,2) ||
653  !lua_to<T1>::can_convert(L,1) ||
655  ) {
656  return lua_notify_last_error(L);
657  }
658  R retval = fptr(
659  lua_to<T1>(L,1),
660  lua_to<T2>(L,2)
661  );
662  lua_push(L,retval);
663  return 1;
664  }
665 
673  template <class R, class T1, class T2, class T3> inline int lua_wrap(
674  lua_State* L, R (*fptr)(T1,T2,T3)
675  ) {
676  if(
677  !lua_check_nb_args(L,3) ||
678  !lua_to<T1>::can_convert(L,1) ||
679  !lua_to<T2>::can_convert(L,2) ||
681  ) {
682  return lua_notify_last_error(L);
683  }
684  R retval = fptr(
685  lua_to<T1>(L,1),
686  lua_to<T2>(L,2),
687  lua_to<T3>(L,3)
688  );
689  lua_push(L,retval);
690  return 1;
691  }
692 
700  template <class R, class T1, class T2, class T3, class T4>
701  inline int lua_wrap(lua_State* L, R (*fptr)(T1,T2,T3,T4)) {
702  if(
703  !lua_check_nb_args(L,4) ||
704  !lua_to<T1>::can_convert(L,1) ||
705  !lua_to<T2>::can_convert(L,2) ||
706  !lua_to<T3>::can_convert(L,3) ||
708  ) {
709  return lua_notify_last_error(L);
710  }
711  R retval = fptr(
712  lua_to<T1>(L,1),
713  lua_to<T2>(L,2),
714  lua_to<T3>(L,3),
715  lua_to<T4>(L,4)
716  );
717  lua_push(L,retval);
718  return 1;
719  }
720 
721  /*************************************************************************/
722 
729  template <> inline int lua_wrap(lua_State* L, void (*fptr)(void)) {
730  if(!lua_check_nb_args(L,0)) {
731  return lua_notify_last_error(L);
732  }
733  fptr();
734  return 0;
735  }
736 
743  template <class T1> inline int lua_wrap(lua_State* L, void (*fptr)(T1)) {
744  if(
745  !lua_check_nb_args(L,1) ||
747  ) {
748  return lua_notify_last_error(L);
749  }
750  fptr(
751  lua_to<T1>(L,1)
752  );
753  return 0;
754  }
755 
762  template <class T1, class T2> inline int lua_wrap(
763  lua_State* L, void (*fptr)(T1,T2)
764  ) {
765  if(
766  !lua_check_nb_args(L,2) ||
767  !lua_to<T1>::can_convert(L,1) ||
769  ) {
770  return lua_notify_last_error(L);
771  }
772  fptr(
773  lua_to<T1>(L,1),
774  lua_to<T2>(L,2)
775  );
776  return 0;
777  }
778 
785  template <class T1, class T2, class T3>
786  inline int lua_wrap(lua_State* L, void (*fptr)(T1,T2,T3)) {
787  if(
788  !lua_check_nb_args(L,3) ||
789  !lua_to<T1>::can_convert(L,1) ||
790  !lua_to<T2>::can_convert(L,2) ||
792  ) {
793  return lua_notify_last_error(L);
794  }
795  fptr(
796  lua_to<T1>(L,1),
797  lua_to<T2>(L,2),
798  lua_to<T3>(L,3)
799  );
800  return 0;
801  }
802 
809  template <class T1, class T2, class T3, class T4>
810  inline int lua_wrap(lua_State* L, void (*fptr)(T1,T2,T3,T4)) {
811  if(
812  !lua_check_nb_args(L,4) ||
813  !lua_to<T1>::can_convert(L,1) ||
814  !lua_to<T2>::can_convert(L,2) ||
815  !lua_to<T3>::can_convert(L,3) ||
817  ) {
818  return lua_notify_last_error(L);
819  }
820  fptr(
821  lua_to<T1>(L,1),
822  lua_to<T2>(L,2),
823  lua_to<T3>(L,3),
824  lua_to<T4>(L,4)
825  );
826  return 0;
827  }
828 
835  template <
836  class T1, class T2, class T3, class T4, class T5
837  >
838  inline int lua_wrap(
839  lua_State* L, void (*fptr)(T1,T2,T3,T4,T5)
840  ) {
841  if(
842  !lua_check_nb_args(L,5) ||
843  !lua_to<T1>::can_convert(L,1) ||
844  !lua_to<T2>::can_convert(L,2) ||
845  !lua_to<T3>::can_convert(L,3) ||
846  !lua_to<T4>::can_convert(L,4) ||
848  ) {
849  return lua_notify_last_error(L);
850  }
851  fptr(
852  lua_to<T1>(L,1),
853  lua_to<T2>(L,2),
854  lua_to<T3>(L,3),
855  lua_to<T4>(L,4),
856  lua_to<T5>(L,5)
857  );
858  return 0;
859  }
860 
867  template <
868  class T1, class T2, class T3, class T4, class T5, class T6
869  >
870  inline int lua_wrap(
871  lua_State* L, void (*fptr)(T1,T2,T3,T4,T5,T6)
872  ) {
873  if(
874  !lua_check_nb_args(L,6) ||
875  !lua_to<T1>::can_convert(L,1) ||
876  !lua_to<T2>::can_convert(L,2) ||
877  !lua_to<T3>::can_convert(L,3) ||
878  !lua_to<T4>::can_convert(L,4) ||
879  !lua_to<T5>::can_convert(L,5) ||
881  ) {
882  return lua_notify_last_error(L);
883  }
884  fptr(
885  lua_to<T1>(L,1),
886  lua_to<T2>(L,2),
887  lua_to<T3>(L,3),
888  lua_to<T4>(L,4),
889  lua_to<T5>(L,5),
890  lua_to<T6>(L,6)
891  );
892  return 0;
893  }
894 
901  template <
902  class T1, class T2, class T3, class T4, class T5,
903  class T6, class T7
904  >
905  inline int lua_wrap(
906  lua_State* L, void (*fptr)(T1,T2,T3,T4,T5,T6,T7)
907  ) {
908  if(
909  !lua_check_nb_args(L,7) ||
910  !lua_to<T1>::can_convert(L,1) ||
911  !lua_to<T2>::can_convert(L,2) ||
912  !lua_to<T3>::can_convert(L,3) ||
913  !lua_to<T4>::can_convert(L,4) ||
914  !lua_to<T5>::can_convert(L,5) ||
915  !lua_to<T6>::can_convert(L,6) ||
917  ) {
918  return lua_notify_last_error(L);
919  }
920  fptr(
921  lua_to<T1>(L,1),
922  lua_to<T2>(L,2),
923  lua_to<T3>(L,3),
924  lua_to<T4>(L,4),
925  lua_to<T5>(L,5),
926  lua_to<T6>(L,6),
927  lua_to<T7>(L,7)
928  );
929  return 0;
930  }
931 
932 
939  template <
940  class T1, class T2, class T3, class T4, class T5,
941  class T6, class T7, class T8
942  >
943  inline int lua_wrap(
944  lua_State* L, void (*fptr)(T1,T2,T3,T4,T5,T6,T7,T8)
945  ) {
946  if(
947  !lua_check_nb_args(L,8) ||
948  !lua_to<T1>::can_convert(L,1) ||
949  !lua_to<T2>::can_convert(L,2) ||
950  !lua_to<T3>::can_convert(L,3) ||
951  !lua_to<T4>::can_convert(L,4) ||
952  !lua_to<T5>::can_convert(L,5) ||
953  !lua_to<T6>::can_convert(L,6) ||
954  !lua_to<T7>::can_convert(L,7) ||
956  ) {
957  return lua_notify_last_error(L);
958  }
959  fptr(
960  lua_to<T1>(L,1),
961  lua_to<T2>(L,2),
962  lua_to<T3>(L,3),
963  lua_to<T4>(L,4),
964  lua_to<T5>(L,5),
965  lua_to<T6>(L,6),
966  lua_to<T7>(L,7),
967  lua_to<T8>(L,8)
968  );
969  return 0;
970  }
971 
972 
979  template <
980  class T1, class T2, class T3, class T4, class T5,
981  class T6, class T7, class T8, class T9
982  >
983  inline int lua_wrap(
984  lua_State* L, void (*fptr)(T1,T2,T3,T4,T5,T6,T7,T8,T9)
985  ) {
986  if(
987  !lua_check_nb_args(L,9) ||
988  !lua_to<T1>::can_convert(L,1) ||
989  !lua_to<T2>::can_convert(L,2) ||
990  !lua_to<T3>::can_convert(L,3) ||
991  !lua_to<T4>::can_convert(L,4) ||
992  !lua_to<T5>::can_convert(L,5) ||
993  !lua_to<T6>::can_convert(L,6) ||
994  !lua_to<T7>::can_convert(L,7) ||
995  !lua_to<T8>::can_convert(L,8) ||
997  ) {
998  return lua_notify_last_error(L);
999  }
1000  fptr(
1001  lua_to<T1>(L,1),
1002  lua_to<T2>(L,2),
1003  lua_to<T3>(L,3),
1004  lua_to<T4>(L,4),
1005  lua_to<T5>(L,5),
1006  lua_to<T6>(L,6),
1007  lua_to<T7>(L,7),
1008  lua_to<T8>(L,8),
1009  lua_to<T9>(L,9)
1010  );
1011  return 0;
1012  }
1013 
1014 
1021  template <
1022  class T1, class T2, class T3, class T4, class T5,
1023  class T6, class T7, class T8, class T9, class T10
1024  >
1025  inline int lua_wrap(
1026  lua_State* L, void (*fptr)(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10)
1027  ) {
1028  if(
1029  !lua_check_nb_args(L,10) ||
1030  !lua_to<T1>::can_convert(L,1) ||
1031  !lua_to<T2>::can_convert(L,2) ||
1032  !lua_to<T3>::can_convert(L,3) ||
1033  !lua_to<T4>::can_convert(L,4) ||
1034  !lua_to<T5>::can_convert(L,5) ||
1035  !lua_to<T6>::can_convert(L,6) ||
1036  !lua_to<T7>::can_convert(L,7) ||
1037  !lua_to<T8>::can_convert(L,8) ||
1038  !lua_to<T9>::can_convert(L,9) ||
1040  ) {
1041  return lua_notify_last_error(L);
1042  }
1043  fptr(
1044  lua_to<T1>(L,1),
1045  lua_to<T2>(L,2),
1046  lua_to<T3>(L,3),
1047  lua_to<T4>(L,4),
1048  lua_to<T5>(L,5),
1049  lua_to<T6>(L,6),
1050  lua_to<T7>(L,7),
1051  lua_to<T8>(L,8),
1052  lua_to<T9>(L,9),
1053  lua_to<T10>(L,10)
1054  );
1055  return 0;
1056  }
1057 
1058 
1065  template <
1066  class T1, class T2, class T3, class T4, class T5,
1067  class T6, class T7, class T8, class T9, class T10,
1068  class T11
1069  >
1070  inline int lua_wrap(
1071  lua_State* L, void (*fptr)(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11)
1072  ) {
1073  if(
1074  !lua_check_nb_args(L,11) ||
1075  !lua_to<T1>::can_convert(L,1) ||
1076  !lua_to<T2>::can_convert(L,2) ||
1077  !lua_to<T3>::can_convert(L,3) ||
1078  !lua_to<T4>::can_convert(L,4) ||
1079  !lua_to<T5>::can_convert(L,5) ||
1080  !lua_to<T6>::can_convert(L,6) ||
1081  !lua_to<T7>::can_convert(L,7) ||
1082  !lua_to<T8>::can_convert(L,8) ||
1083  !lua_to<T9>::can_convert(L,9) ||
1084  !lua_to<T10>::can_convert(L,10) ||
1086  ) {
1087  return lua_notify_last_error(L);
1088  }
1089  fptr(
1090  lua_to<T1>(L,1),
1091  lua_to<T2>(L,2),
1092  lua_to<T3>(L,3),
1093  lua_to<T4>(L,4),
1094  lua_to<T5>(L,5),
1095  lua_to<T6>(L,6),
1096  lua_to<T7>(L,7),
1097  lua_to<T8>(L,8),
1098  lua_to<T9>(L,9),
1099  lua_to<T10>(L,10),
1100  lua_to<T11>(L,11)
1101  );
1102  return 0;
1103  }
1104 
1111  template <
1112  class T1, class T2, class T3, class T4, class T5,
1113  class T6, class T7, class T8, class T9, class T10,
1114  class T11, class T12
1115  >
1116  inline int lua_wrap(
1117  lua_State* L, void (*fptr)(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12)
1118  ) {
1119  if(
1120  !lua_check_nb_args(L,12) ||
1121  !lua_to<T1>::can_convert(L,1) ||
1122  !lua_to<T2>::can_convert(L,2) ||
1123  !lua_to<T3>::can_convert(L,3) ||
1124  !lua_to<T4>::can_convert(L,4) ||
1125  !lua_to<T5>::can_convert(L,5) ||
1126  !lua_to<T6>::can_convert(L,6) ||
1127  !lua_to<T7>::can_convert(L,7) ||
1128  !lua_to<T8>::can_convert(L,8) ||
1129  !lua_to<T9>::can_convert(L,9) ||
1130  !lua_to<T10>::can_convert(L,10) ||
1131  !lua_to<T11>::can_convert(L,11) ||
1133  ) {
1134  return lua_notify_last_error(L);
1135  }
1136  fptr(
1137  lua_to<T1>(L,1),
1138  lua_to<T2>(L,2),
1139  lua_to<T3>(L,3),
1140  lua_to<T4>(L,4),
1141  lua_to<T5>(L,5),
1142  lua_to<T6>(L,6),
1143  lua_to<T7>(L,7),
1144  lua_to<T8>(L,8),
1145  lua_to<T9>(L,9),
1146  lua_to<T10>(L,10),
1147  lua_to<T11>(L,11),
1148  lua_to<T12>(L,12)
1149  );
1150  return 0;
1151  }
1152 
1153 
1160  template <
1161  class T1, class T2, class T3, class T4, class T5,
1162  class T6, class T7, class T8, class T9, class T10,
1163  class T11, class T12, class T13
1164  >
1165  inline int lua_wrap(
1166  lua_State* L, void (*fptr)(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13)
1167  ) {
1168  if(
1169  !lua_check_nb_args(L,13) ||
1170  !lua_to<T1>::can_convert(L,1) ||
1171  !lua_to<T2>::can_convert(L,2) ||
1172  !lua_to<T3>::can_convert(L,3) ||
1173  !lua_to<T4>::can_convert(L,4) ||
1174  !lua_to<T5>::can_convert(L,5) ||
1175  !lua_to<T6>::can_convert(L,6) ||
1176  !lua_to<T7>::can_convert(L,7) ||
1177  !lua_to<T8>::can_convert(L,8) ||
1178  !lua_to<T9>::can_convert(L,9) ||
1179  !lua_to<T10>::can_convert(L,10) ||
1180  !lua_to<T11>::can_convert(L,11) ||
1181  !lua_to<T12>::can_convert(L,12) ||
1183  ) {
1184  return lua_notify_last_error(L);
1185  }
1186  fptr(
1187  lua_to<T1>(L,1),
1188  lua_to<T2>(L,2),
1189  lua_to<T3>(L,3),
1190  lua_to<T4>(L,4),
1191  lua_to<T5>(L,5),
1192  lua_to<T6>(L,6),
1193  lua_to<T7>(L,7),
1194  lua_to<T8>(L,8),
1195  lua_to<T9>(L,9),
1196  lua_to<T10>(L,10),
1197  lua_to<T11>(L,11),
1198  lua_to<T12>(L,12),
1199  lua_to<T13>(L,13)
1200  );
1201  return 0;
1202  }
1203 
1210  template<> inline int lua_wrap(lua_State* L, lua_CFunction fptr) {
1211  return fptr(L);
1212  }
1213 
1214 
1215  /*************************************************************************/
1216 
1224  template <class FPTR> class lua_wrapper {
1225  public:
1226 
1235  static int call(lua_State* L) {
1236  FPTR f = FPTR(
1238  lua_touserdata(L, lua_upvalueindex(1))
1239  )
1240  );
1241  return lua_wrap(L, f);
1242  }
1243 
1250  static void push(lua_State* L, FPTR f) {
1251  lua_pushlightuserdata(
1252  L,
1255  )
1256  );
1257  lua_pushcclosure(L, lua_wrapper<FPTR>::call, 1);
1258  }
1259  };
1260 
1261  /**************************************************************************/
1262 
1269  template <class FPTR> inline void lua_pushwrapper(lua_State* L, FPTR f) {
1271  }
1272 
1277  template<> inline void lua_pushwrapper(lua_State* L, lua_CFunction f) {
1278  lua_pushcfunction(L,f);
1279  }
1280 
1281  /**************************************************************************/
1282 
1291  template <class FPTR> inline void lua_bindwrapperwithname(
1292  lua_State* L, FPTR f, const std::string& name
1293  ) {
1294  geo_assert(lua_gettop(L) > 0);
1295  geo_assert(lua_istable(L,-1));
1296  lua_pushstring(L,name.c_str());
1297  lua_pushwrapper(L,f);
1298  lua_settable(L,-3);
1299  }
1300 
1301 
1308  template <class FPTR> inline void lua_bindwrapperwithnameglobal(
1309  lua_State* L, FPTR f, const std::string& name
1310  ) {
1311  lua_pushwrapper(L,f);
1312  lua_setglobal(L,name.c_str());
1313  }
1314 
1315  /**************************************************************************/
1316 
1324  inline std::string lua_wrappername(lua_State* L, const char* functionname) {
1325  geo_argused(L);
1326  std::string result(functionname);
1327  size_t pos = result.find_last_of(":");
1328  if(pos != std::string::npos) {
1329  result = result.substr(pos+1, result.length()-pos);
1330  }
1331  return result;
1332  }
1333 
1334  /**************************************************************************/
1335 
1351 #define lua_bindwrapper(L, f) lua_bindwrapperwithname( \
1352  (L),(f),GEO::lua_wrappername(L,#f) \
1353  )
1354 
1369 #define lua_bindwrapperglobal(L, f) lua_bindwrapperwithnameglobal( \
1370  (L),(f),GEO::lua_wrappername(L,#f) \
1371  )
1372 
1373 
1374  /*************************************************************************/
1375 
1376 }
1377 
1378 #ifdef GEO_COMPILER_MSVC
1379 #pragma warning( pop )
1380 #endif
1381 
1382 #endif
Assertion checking mechanism.
#define geo_assert_not_reached
Sets a non reachable point in the program.
Definition: assert.h:177
#define geo_assert(x)
Verifies that a condition is met.
Definition: assert.h:149
Converts LUA variables to C++ variables.
Definition: lua_wrap.h:243
static bool can_convert(lua_State *L, int idx)
Tests whether a LUA variable can be converted to a C++ variable.
Definition: lua_wrap.h:275
lua_to(lua_State *L, int idx)
lua_to constructor.
Definition: lua_wrap.h:257
Manages wrappers around C++ functions to be called from LUA.
Definition: lua_wrap.h:1224
static int call(lua_State *L)
Implementation of the wrapper.
Definition: lua_wrap.h:1235
static void push(lua_State *L, FPTR f)
Pushes a wrapper for a given C++ function onto the LUA stack.
Definition: lua_wrap.h:1250
Common include file, providing basic definitions. Should be included before anything else by all head...
Types and functions for memory manipulation.
void(* function_pointer)()
Generic function pointer.
Definition: memory.h:107
pointer function_pointer_to_generic_pointer(function_pointer fptr)
Converts a function pointer to a generic pointer.
Definition: memory.h:142
function_pointer generic_pointer_to_function_pointer(pointer ptr)
Converts a generic pointer to a function pointer.
Definition: memory.h:161
uint64_t uint64
Definition: numeric.h:144
uint32_t uint32
Definition: numeric.h:141
int64_t int64
Definition: numeric.h:132
Global Vorpaline namespace.
Definition: basic.h:55
std::string lua_wrappername(lua_State *L, const char *functionname)
Converts a C++ function name into a LUA function name.
Definition: lua_wrap.h:1324
int my_lua_isboolean(lua_State *L, int idx)
Tests whether a LUA variable is a boolean.
Definition: lua_wrap.h:84
void lua_bindwrapperwithnameglobal(lua_State *L, FPTR f, const std::string &name)
Binds a wrapper to a name in the global scole.
Definition: lua_wrap.h:1308
bool lua_check_type(lua_State *L, int idx, lua_test_func test)
Tests whether a LUA variable has the correct type.
Definition: lua_wrap.h:178
void lua_set_error(lua_State *L, const char *error)
Memorizes an error message in LUA registry.
Definition: lua_wrap.h:128
void lua_bindwrapperwithname(lua_State *L, FPTR f, const std::string &name)
Binds a wrapper to a name in the table at the top of the LUA stack.
Definition: lua_wrap.h:1291
void lua_clear_error(lua_State *L)
Clears the last error message in LUA registry.
Definition: lua_wrap.h:149
void geo_argused(const T &)
Suppresses compiler warnings about unused parameters.
Definition: argused.h:60
int my_lua_islightuserdata(lua_State *L, int idx)
Tests whether a LUA variable is a light user data.
Definition: lua_wrap.h:99
void lua_push(lua_State *L, T x)
Converts and pushes a C++ variable onto the LUA stack.
Definition: lua_wrap.h:484
bool lua_check_nb_args(lua_State *L, int expected_nb_args)
Tests whether the expected number of arguments was pushed onto the stack.
Definition: lua_wrap.h:201
int my_lua_ispositiveinteger(lua_State *L, int idx)
Tests whether a LUA variable is a positive integer.
Definition: lua_wrap.h:112
bool lua_has_error(lua_State *L)
Tests whether an error message was memorized in the registry.
Definition: lua_wrap.h:159
int lua_notify_last_error(lua_State *L)
Takes the last error message memorized in the registry and sends it back to LUA.
Definition: lua_wrap.h:225
int(* lua_test_func)(lua_State *L, int idx)
A pointer to a LUA function to test an argument in the LUA stack.
Definition: lua_wrap.h:70
void lua_pushwrapper(lua_State *L, FPTR f)
Pushes a wrapper for a given C++ function onto the LUA stack.
Definition: lua_wrap.h:1269
int lua_wrap(lua_State *L, R(*fptr)(void))
Calls a C++ function from LUA.
Definition: lua_wrap.h:609
Types and functions for numbers manipulation.
Functions for string manipulation.