e6ff637f190041a830059c086a9db8e2de1bf271
[ardour.git] / libs / lua / LuaBridge / detail / Stack.h
1 //------------------------------------------------------------------------------
2 /*
3   https://github.com/vinniefalco/LuaBridge
4
5   Copyright 2016, Robin Gareus <robin@gareus.org>
6   Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
7   Copyright 2007, Nathan Reed
8
9   License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
10
11   Permission is hereby granted, free of charge, to any person obtaining a copy
12   of this software and associated documentation files (the "Software"), to deal
13   in the Software without restriction, including without limitation the rights
14   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15   copies of the Software, and to permit persons to whom the Software is
16   furnished to do so, subject to the following conditions:
17
18   The above copyright notice and this permission notice shall be included in all
19   copies or substantial portions of the Software.
20
21   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27   SOFTWARE.
28 */
29 //==============================================================================
30
31 //------------------------------------------------------------------------------
32 /**
33     Receive the lua_State* as an argument.
34 */
35 template <>
36 struct Stack <lua_State*>
37 {
38   static lua_State* get (lua_State* L, int)
39   {
40     return L;
41   }
42 };
43
44 //------------------------------------------------------------------------------
45 /**
46     Push a lua_CFunction.
47 */
48 template <>
49 struct Stack <lua_CFunction>
50 {
51   static void push (lua_State* L, lua_CFunction f)
52   {
53     lua_pushcfunction (L, f);
54   }
55
56   static lua_CFunction get (lua_State* L, int index)
57   {
58     return lua_tocfunction (L, index);
59   }
60 };
61
62 //------------------------------------------------------------------------------
63 /**
64     Stack specialization for passing references to built-in types.
65
66     This allows to call functions using primitives, but
67     the value assigned by the C++ function is *lost*.
68
69     http://sourceforge.net/p/luabind/mailman/message/32692027/
70
71     Alternatives:
72      - wrap all C++ function that have non const reference arguments
73     (cleanest solution)
74
75      - use a struct to wrap the value (not a primitive)
76     (needs major work to special case arguments in CFunc::)
77
78      - wrap the function and provide the assigned value
79      as addition return values
80
81     Either would place hard constraints on the lua code though.
82
83     We currently only need this for Ardour::Editor::do_import() framecnt_t&
84     and the returned position is not important.
85 */
86
87 //------------------------------------------------------------------------------
88 /**
89     Stack specialization for `int`.
90 */
91 template <>
92 struct Stack <int>
93 {
94   static inline void push (lua_State* L, int value)
95   {
96     lua_pushinteger (L, static_cast <lua_Integer> (value));
97   }
98
99   static inline int get (lua_State* L, int index)
100   {
101     return static_cast <int> (luaL_checkinteger (L, index));
102   }
103 };
104
105 template <>
106 struct Stack <int const&>
107 {
108   static inline void push (lua_State* L, int value)
109   {
110     lua_pushnumber (L, static_cast <lua_Number> (value));
111   }
112
113   static inline int get (lua_State* L, int index)
114   {
115     return static_cast <int > (luaL_checknumber (L, index));
116   }
117 };
118
119 template <>
120 struct Stack <int &>
121 {
122   static inline void push (lua_State* L, int &value)
123   {
124     lua_pushnumber (L, static_cast <lua_Number> (value));
125   }
126
127   static inline int& get (lua_State* L, int index)
128   {
129     int l = static_cast <int> (luaL_checknumber (L, index));
130     int* x = new (lua_newuserdata (L, sizeof (int))) int (l);
131     return *x;
132   }
133 };
134
135 //------------------------------------------------------------------------------
136 /**
137     Stack specialization for `unsigned int`.
138 */
139 template <>
140 struct Stack <unsigned int>
141 {
142   static inline void push (lua_State* L, unsigned int value)
143   {
144     lua_pushinteger (L, static_cast <lua_Integer> (value));
145   }
146
147   static inline unsigned int get (lua_State* L, int index)
148   {
149     return static_cast <unsigned int> (luaL_checkinteger (L, index));
150   }
151 };
152
153 template <>
154 struct Stack <unsigned int const&>
155 {
156   static inline void push (lua_State* L, unsigned int value)
157   {
158     lua_pushnumber (L, static_cast <lua_Number> (value));
159   }
160
161   static inline unsigned int get (lua_State* L, int index)
162   {
163     return static_cast <unsigned int > (luaL_checknumber (L, index));
164   }
165 };
166
167 template <>
168 struct Stack <unsigned int &>
169 {
170   static inline void push (lua_State* L, unsigned int& value)
171   {
172     lua_pushnumber (L, static_cast <lua_Number> (value));
173   }
174
175   static inline unsigned int& get (lua_State* L, int index)
176   {
177     unsigned int l = static_cast <unsigned int> (luaL_checknumber (L, index));
178     unsigned int* x = new (lua_newuserdata (L, sizeof (unsigned int))) unsigned int (l);
179     return *x;
180   }
181 };
182
183 //------------------------------------------------------------------------------
184 /**
185     Stack specialization for `unsigned char`.
186 */
187 template <>
188 struct Stack <unsigned char>
189 {
190   static inline void push (lua_State* L, unsigned char value)
191   {
192     lua_pushinteger (L, static_cast <lua_Integer> (value));
193   }
194
195   static inline unsigned char get (lua_State* L, int index)
196   {
197     return static_cast <unsigned char> (luaL_checkinteger (L, index));
198   }
199 };
200
201 template <>
202 struct Stack <unsigned char const&>
203 {
204   static inline void push (lua_State* L, unsigned char value)
205   {
206     lua_pushnumber (L, static_cast <lua_Number> (value));
207   }
208
209   static inline unsigned char get (lua_State* L, int index)
210   {
211     return static_cast <unsigned char> (luaL_checknumber (L, index));
212   }
213 };
214
215 template <>
216 struct Stack <unsigned char &>
217 {
218   static inline void push (lua_State* L, unsigned char& value)
219   {
220     lua_pushnumber (L, static_cast <lua_Number> (value));
221   }
222
223   static inline unsigned char& get (lua_State* L, int index)
224   {
225     unsigned char l = static_cast <unsigned char> (luaL_checknumber (L, index));
226     unsigned char* x = new (lua_newuserdata (L, sizeof (unsigned char))) unsigned char (l);
227     return *x;
228   }
229 };
230
231 //------------------------------------------------------------------------------
232 /**
233     Stack specialization for `short`.
234 */
235 template <>
236 struct Stack <short>
237 {
238   static inline void push (lua_State* L, short value)
239   {
240     lua_pushinteger (L, static_cast <lua_Integer> (value));
241   }
242
243   static inline short get (lua_State* L, int index)
244   {
245     return static_cast <short> (luaL_checkinteger (L, index));
246   }
247 };
248
249 template <>
250 struct Stack <short const&>
251 {
252   static inline void push (lua_State* L, short value)
253   {
254     lua_pushnumber (L, static_cast <lua_Number> (value));
255   }
256
257   static inline short get (lua_State* L, int index)
258   {
259     return static_cast <short> (luaL_checknumber (L, index));
260   }
261 };
262
263 template <>
264 struct Stack <short &>
265 {
266   static inline void push (lua_State* L, short& value)
267   {
268     lua_pushnumber (L, static_cast <lua_Number> (value));
269   }
270
271   static inline short& get (lua_State* L, int index)
272   {
273     short l = static_cast <short> (luaL_checknumber (L, index));
274     short* x = new (lua_newuserdata (L, sizeof (short))) short (l);
275     return *x;
276   }
277 };
278
279 //------------------------------------------------------------------------------
280 /**
281     Stack specialization for `unsigned short`.
282 */
283 template <>
284 struct Stack <unsigned short>
285 {
286   static inline void push (lua_State* L, unsigned short value)
287   {
288     lua_pushinteger (L, static_cast <lua_Integer> (value));
289   }
290
291   static inline unsigned short get (lua_State* L, int index)
292   {
293     return static_cast <unsigned short> (luaL_checkinteger (L, index));
294   }
295 };
296
297 template <>
298 struct Stack <unsigned short const&>
299 {
300   static inline void push (lua_State* L, unsigned short value)
301   {
302     lua_pushnumber (L, static_cast <lua_Number> (value));
303   }
304
305   static inline unsigned short get (lua_State* L, int index)
306   {
307     return static_cast <unsigned short> (luaL_checknumber (L, index));
308   }
309 };
310
311 template <>
312 struct Stack <unsigned short &>
313 {
314   static inline void push (lua_State* L, unsigned short& value)
315   {
316     lua_pushnumber (L, static_cast <lua_Number> (value));
317   }
318
319   static inline unsigned short& get (lua_State* L, int index)
320   {
321     unsigned short l = static_cast <unsigned short> (luaL_checknumber (L, index));
322     unsigned short* x = new (lua_newuserdata (L, sizeof (unsigned short))) unsigned short (l);
323     return *x;
324   }
325 };
326
327 //------------------------------------------------------------------------------
328 /**
329     Stack specialization for `long`.
330 */
331 template <>
332 struct Stack <long>
333 {
334   static inline void push (lua_State* L, long value)
335   {
336     lua_pushinteger (L, static_cast <lua_Integer> (value));
337   }
338
339   static inline long get (lua_State* L, int index)
340   {
341     return static_cast <long> (luaL_checkinteger (L, index));
342   }
343 };
344
345 template <>
346 struct Stack <long const&>
347 {
348   static inline void push (lua_State* L, long value)
349   {
350     lua_pushnumber (L, static_cast <lua_Number> (value));
351   }
352
353   static inline long get (lua_State* L, int index)
354   {
355     return static_cast <long> (luaL_checknumber (L, index));
356   }
357 };
358
359 template <>
360 struct Stack <long &>
361 {
362   static inline void push (lua_State* L, long& value)
363   {
364     lua_pushnumber (L, static_cast <lua_Number> (value));
365   }
366
367   static inline long& get (lua_State* L, int index)
368   {
369     long l = static_cast <long> (luaL_checknumber (L, index));
370     long* x = new (lua_newuserdata (L, sizeof (long))) long (l);
371     return *x;
372   }
373 };
374
375 //------------------------------------------------------------------------------
376 /**
377     Stack specialization for `unsigned long`.
378 */
379 template <>
380 struct Stack <unsigned long>
381 {
382   static inline void push (lua_State* L, unsigned long value)
383   {
384     lua_pushinteger (L, static_cast <lua_Integer> (value));
385   }
386
387   static inline unsigned long get (lua_State* L, int index)
388   {
389     return static_cast <unsigned long> (luaL_checkinteger (L, index));
390   }
391 };
392
393 template <>
394 struct Stack <unsigned long const&>
395 {
396   static inline void push (lua_State* L, unsigned long value)
397   {
398     lua_pushnumber (L, static_cast <lua_Number> (value));
399   }
400
401   static inline unsigned long get (lua_State* L, int index)
402   {
403     return static_cast <unsigned long> (luaL_checknumber (L, index));
404   }
405 };
406
407 template <>
408 struct Stack <unsigned long &>
409 {
410   static inline void push (lua_State* L, unsigned long& value)
411   {
412     lua_pushnumber (L, static_cast <lua_Number> (value));
413   }
414
415   static inline unsigned long& get (lua_State* L, int index)
416   {
417     unsigned long l = static_cast <unsigned long> (luaL_checknumber (L, index));
418     unsigned long* x = new (lua_newuserdata (L, sizeof (unsigned long))) unsigned long (l);
419     return *x;
420   }
421 };
422
423 //------------------------------------------------------------------------------
424 /**
425     Stack specialization for `long long`.
426 */
427 template <>
428 struct Stack <long long>
429 {
430   static inline void push (lua_State* L, long long value)
431   {
432     lua_pushinteger (L, static_cast <lua_Integer> (value));
433   }
434
435   static inline long long get (lua_State* L, int index)
436   {
437     return static_cast <long long> (luaL_checkinteger (L, index));
438   }
439 };
440
441 template <>
442 struct Stack <long long const&>
443 {
444   static inline void push (lua_State* L, long long value)
445   {
446     lua_pushnumber (L, static_cast <lua_Number> (value));
447   }
448
449   static inline long long get (lua_State* L, int index)
450   {
451     return static_cast <long long> (luaL_checknumber (L, index));
452   }
453 };
454
455 template <>
456 struct Stack <long long &>
457 {
458   static inline void push (lua_State* L, long long& value)
459   {
460     lua_pushnumber (L, static_cast <lua_Number> (value));
461   }
462
463   static inline long long& get (lua_State* L, int index)
464   {
465     long long l = static_cast <long long> (luaL_checknumber (L, index));
466     long long* x = new (lua_newuserdata (L, sizeof (long long))) long long (l);
467     return *x;
468   }
469 };
470
471 //------------------------------------------------------------------------------
472 /**
473     Stack specialization for `unsigned long long`.
474 */
475 template <>
476 struct Stack <unsigned long long>
477 {
478   static inline void push (lua_State* L, unsigned long long value)
479   {
480     lua_pushinteger (L, static_cast <lua_Integer> (value));
481   }
482
483   static inline unsigned long long get (lua_State* L, int index)
484   {
485     return static_cast <unsigned long long> (luaL_checkinteger (L, index));
486   }
487 };
488
489 template <>
490 struct Stack <unsigned long long const&>
491 {
492   static inline void push (lua_State* L, unsigned long long value)
493   {
494     lua_pushnumber (L, static_cast <lua_Number> (value));
495   }
496
497   static inline unsigned long long get (lua_State* L, int index)
498   {
499     return static_cast <unsigned long long> (luaL_checknumber (L, index));
500   }
501 };
502
503 //------------------------------------------------------------------------------
504 /**
505     Stack specialization for `float`.
506 */
507 template <>
508 struct Stack <float>
509 {
510   static inline void push (lua_State* L, float value)
511   {
512     lua_pushnumber (L, static_cast <lua_Number> (value));
513   }
514
515   static inline float get (lua_State* L, int index)
516   {
517     return static_cast <float> (luaL_checknumber (L, index));
518   }
519 };
520
521 template <>
522 struct Stack <float const&>
523 {
524   static inline void push (lua_State* L, float value)
525   {
526     lua_pushnumber (L, static_cast <lua_Number> (value));
527   }
528
529   static inline float get (lua_State* L, int index)
530   {
531     return static_cast <float> (luaL_checknumber (L, index));
532   }
533 };
534
535 template <>
536 struct Stack <float &>
537 {
538   static inline void push (lua_State* L, float& value)
539   {
540     lua_pushnumber (L, static_cast <lua_Number> (value));
541   }
542
543   static inline float& get (lua_State* L, int index)
544   {
545     float l = static_cast <float> (luaL_checknumber (L, index));
546     float* x = new (lua_newuserdata (L, sizeof (float))) float (l);
547     return *x;
548   }
549 };
550
551 //------------------------------------------------------------------------------
552 /**
553     Stack specialization for `double`.
554 */
555 template <> struct Stack <double>
556 {
557   static inline void push (lua_State* L, double value)
558   {
559     lua_pushnumber (L, static_cast <lua_Number> (value));
560   }
561
562   static inline double get (lua_State* L, int index)
563   {
564     return static_cast <double> (luaL_checknumber (L, index));
565   }
566 };
567
568 template <> struct Stack <double const&>
569 {
570   static inline void push (lua_State* L, double value)
571   {
572     lua_pushnumber (L, static_cast <lua_Number> (value));
573   }
574
575   static inline double get (lua_State* L, int index)
576   {
577     return static_cast <double> (luaL_checknumber (L, index));
578   }
579 };
580
581 template <> struct Stack <double &>
582 {
583   static inline void push (lua_State* L, double& value)
584   {
585     lua_pushnumber (L, static_cast <lua_Number> (value));
586   }
587
588   static inline double& get (lua_State* L, int index)
589   {
590     double l = static_cast <double> (luaL_checknumber (L, index));
591     double* x = new (lua_newuserdata (L, sizeof (double))) double (l);
592     return *x;
593   }
594 };
595
596 //------------------------------------------------------------------------------
597 /**
598     Stack specialization for `bool`.
599 */
600 template <>
601 struct Stack <bool> {
602   static inline void push (lua_State* L, bool value)
603   {
604     lua_pushboolean (L, value ? 1 : 0);
605   }
606
607   static inline bool get (lua_State* L, int index)
608   {
609     return lua_toboolean (L, index) ? true : false;
610   }
611 };
612
613 template <>
614 struct Stack <bool const&> {
615   static inline void push (lua_State* L, bool value)
616   {
617     lua_pushboolean (L, value ? 1 : 0);
618   }
619
620   static inline bool get (lua_State* L, int index)
621   {
622     return lua_toboolean (L, index) ? true : false;
623   }
624 };
625
626 template <>
627 struct Stack <bool &> {
628   static inline void push (lua_State* L, bool& value)
629   {
630     lua_pushboolean (L, value ? 1 : 0);
631   }
632
633   static inline bool& get (lua_State* L, int index)
634   {
635     bool l = lua_toboolean (L, index) ? true : false;
636     bool* x = new (lua_newuserdata (L, sizeof (bool))) bool (l);
637     return *x;
638   }
639 };
640
641 //------------------------------------------------------------------------------
642 /**
643     Stack specialization for `char`.
644 */
645 template <>
646 struct Stack <char>
647 {
648   static inline void push (lua_State* L, char value)
649   {
650     char str [2] = { value, 0 };
651     lua_pushstring (L, str);
652   }
653
654   static inline char get (lua_State* L, int index)
655   {
656     return luaL_checkstring (L, index) [0];
657   }
658 };
659
660 template <>
661 struct Stack <char const&>
662 {
663   static inline void push (lua_State* L, char value)
664   {
665     char str [2] = { value, 0 };
666     lua_pushstring (L, str);
667   }
668
669   static inline char get (lua_State* L, int index)
670   {
671     return luaL_checkstring (L, index) [0];
672   }
673 };
674
675 template <>
676 struct Stack <char const *>
677 {
678   static inline void push (lua_State* L, char const* str)
679   {
680     if (str != 0)
681       lua_pushstring (L, str);
682     else
683       lua_pushnil (L);
684   }
685
686   static inline char const *get (lua_State* L, int index)
687   {
688     return lua_isnil (L, index) ? 0 : luaL_checkstring (L, index);
689   }
690 };
691
692 template <>
693 struct Stack <char &>
694 {
695   static inline void push (lua_State* L, char& value)
696   {
697     char str [2] = { value, 0 };
698     lua_pushstring (L, str);
699   }
700
701   static inline char get (lua_State* L, int index)
702   {
703     char l = luaL_checkstring (L, index) [0];
704     char* x = new (lua_newuserdata (L, sizeof (char))) char (l);
705     return *x;
706   }
707 };
708
709 //------------------------------------------------------------------------------
710 /**
711     Stack specialization for `std::string`.
712 */
713 template <>
714 struct Stack <std::string>
715 {
716   static inline void push (lua_State* L, std::string const& str)
717   {
718     lua_pushlstring (L, str.c_str (), str.size());
719   }
720
721   static inline std::string get (lua_State* L, int index)
722   {
723     size_t len;
724     const char *str = luaL_checklstring(L, index, &len);
725     return std::string (str, len);
726   }
727 };
728
729 template <>
730 struct Stack <std::string const&>
731 {
732   static inline void push (lua_State* L, std::string const& str)
733   {
734     lua_pushstring (L, str.c_str());
735   }
736
737   static inline std::string get (lua_State* L, int index)
738   {
739     size_t len;
740     const char *str = luaL_checklstring(L, index, &len);
741     return std::string (str, len);
742   }
743 };
744
745 template <>
746 struct Stack <std::string &>
747 {
748   static inline void push (lua_State* L, std::string& str)
749   {
750     lua_pushlstring (L, str.c_str (), str.size());
751   }
752
753   static inline std::string& get (lua_State* L, int index)
754   {
755     size_t len;
756     const char *str = luaL_checklstring(L, index, &len);
757     std::string* x = new (lua_newuserdata (L, sizeof (std::string))) std::string (str, len);
758     return *x;
759   }
760 };