1 //------------------------------------------------------------------------------ 2 /* 3 https://github.com/vinniefalco/LuaBridge 4 5 Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com> 6 Copyright 2008, Nigel Atkinson <suprapilot+LuaCode@gmail.com> 7 8 License: The MIT License (http://www.opensource.org/licenses/mit-license.php) 9 10 Permission is hereby granted, free of charge, to any person obtaining a copy 11 of this software and associated documentation files (the "Software"), to deal 12 in the Software without restriction, including without limitation the rights 13 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 copies of the Software, and to permit persons to whom the Software is 15 furnished to do so, subject to the following conditions: 16 17 The above copyright notice and this permission notice shall be included in all 18 copies or substantial portions of the Software. 19 20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 SOFTWARE. 27 */ 28 //============================================================================== 29 30 //------------------------------------------------------------------------------ 31 /** 32 Type tag for representing LUA_TNIL. 33 34 Construct one of these using `Nil()` to represent a Lua nil. This is faster 35 than creating a reference in the registry to nil. Example: 36 37 LuaRef t (LuaRef::createTable (L)); 38 ... 39 t ["k"] = Nil(); // assign nil 40 */ 41 struct Nil 42 { 43 }; 44 45 //------------------------------------------------------------------------------ 46 /** 47 Lightweight reference to a Lua object. 48 49 The reference is maintained for the lifetime of the C++ object. 50 */ 51 class LuaRef 52 { 53 private: 54 class Proxy; 55 friend struct Stack <Proxy>; 56 57 //---------------------------------------------------------------------------- 58 /** 59 Pop the Lua stack. 60 61 Pops the specified number of stack items on destruction. We use this 62 when returning objects, to avoid an explicit temporary variable, since 63 the destructor executes after the return statement. For example: 64 65 \code 66 template <class U> 67 U cast (lua_State* L) 68 { 69 StackPop p (L, 1); 70 ... 71 return U (); // dtor called after this line 72 } 73 \endcode 74 75 @note The `StackPop` object must always be a named local variable. 76 */ 77 class StackPop 78 { 79 public: 80 /** Create a StackPop object. 81 82 @param L the LuaState to modify 83 @param count The number of stack entries to pop on destruction. 84 */ 85 StackPop (lua_State* L, int count) 86 : m_L (L) 87 , m_count (count) 88 { 89 } 90 91 ~StackPop () 92 { 93 lua_pop (m_L, m_count); 94 } 95 96 private: 97 lua_State* m_L; 98 int m_count; 99 }; 100 101 //---------------------------------------------------------------------------- 102 /** 103 A proxy for representing table values. 104 */ 105 class Proxy 106 { 107 private: 108 lua_State* m_L; 109 int m_tableRef; 110 int m_keyRef; 111 112 public: 113 //-------------------------------------------------------------------------- 114 /** 115 Construct a Proxy from a table value. 116 117 The table is in the registry, and the key is at the top of the stack. 118 The key is popped off the stack. 119 */ 120 Proxy (lua_State* L, int tableRef) 121 : m_L (L) 122 , m_tableRef (tableRef) 123 , m_keyRef (luaL_ref (L, LUA_REGISTRYINDEX)) 124 { 125 } 126 127 //-------------------------------------------------------------------------- 128 /** 129 Create a Proxy via copy constructor. 130 131 It is best to avoid code paths that invoke this, because it creates 132 an extra temporary Lua reference. Typically this is done by passing 133 the Proxy parameter as a `const` reference. 134 */ 135 Proxy (Proxy const& other) 136 : m_L (other.m_L) 137 , m_tableRef (other.m_tableRef) 138 { 139 // If this assert goes off it means code is taking this path, 140 // which is better avoided. 141 // 142 assert (0); 143 144 lua_rawgeti (m_L, LUA_REGISTRYINDEX, other.m_keyRef); 145 m_keyRef = luaL_ref (m_L, LUA_REGISTRYINDEX); 146 } 147 148 //-------------------------------------------------------------------------- 149 /** 150 Destroy the proxy. 151 152 This does not destroy the table value. 153 */ 154 ~Proxy () 155 { 156 luaL_unref (m_L, LUA_REGISTRYINDEX, m_keyRef); 157 } 158 159 //-------------------------------------------------------------------------- 160 /** 161 Return a reference to the table value. 162 */ 163 int createRef () const 164 { 165 push (m_L); 166 return luaL_ref (m_L, LUA_REGISTRYINDEX); 167 } 168 169 //-------------------------------------------------------------------------- 170 /** 171 Assign a new value to this table key. 172 173 This may invoke metamethods. 174 */ 175 template <class T> 176 Proxy& operator= (T v) 177 { 178 StackPop p (m_L, 1); 179 lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_tableRef); 180 lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_keyRef); 181 Stack <T>::push (m_L, v); 182 lua_rawset (m_L, -3); 183 return *this; 184 } 185 186 // the implementation needs UserdataPtr, which 187 // is not yet defined here. 188 // -> libs/ardour/lua_api.cc 189 Proxy& clone_instance (const void* key, void* p); 190 191 //-------------------------------------------------------------------------- 192 /** 193 Assign a new value to this table key. 194 195 The assignment is raw, no metamethods are invoked. 196 */ 197 template <class T> 198 Proxy& rawset (T v) 199 { 200 StackPop p (m_L, 1); 201 lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_tableRef); 202 lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_keyRef); 203 Stack <T>::push (m_L, v); 204 lua_settable (m_L, -3); 205 return *this; 206 } 207 208 //========================================================================== 209 // 210 // This group of member functions mirrors the member functions in LuaRef. 211 212 /** Retrieve the lua_State associated with the table value. 213 */ 214 lua_State* state () const 215 { 216 return m_L; 217 } 218 219 //-------------------------------------------------------------------------- 220 /** 221 Push the value onto the Lua stack. 222 */ 223 void push (lua_State* L) const 224 { 225 assert (equalstates (L, m_L)); 226 lua_rawgeti (L, LUA_REGISTRYINDEX, m_tableRef); 227 lua_rawgeti (L, LUA_REGISTRYINDEX, m_keyRef); 228 lua_gettable (L, -2); 229 lua_remove (L, -2); // remove the table 230 } 231 232 //-------------------------------------------------------------------------- 233 /** 234 Determine the object type. 235 236 The return values are the same as for `lua_type`. 237 */ 238 int type () const 239 { 240 int result; 241 push (m_L); 242 result = lua_type (m_L, -1); 243 lua_pop (m_L, 1); 244 return result; 245 } 246 247 inline bool isNil () const { return type () == LUA_TNIL; } 248 inline bool isBoolean () const { return type () == LUA_TBOOLEAN; } 249 inline bool isNumber () const { return type () == LUA_TNUMBER; } 250 inline bool isString () const { return type () == LUA_TSTRING; } 251 inline bool isTable () const { return type () == LUA_TTABLE; } 252 inline bool isFunction () const { return type () == LUA_TFUNCTION; } 253 inline bool isUserdata () const { return type () == LUA_TUSERDATA; } 254 inline bool isThread () const { return type () == LUA_TTHREAD; } 255 inline bool isLightUserdata () const { return type () == LUA_TLIGHTUSERDATA; } 256 257 //-------------------------------------------------------------------------- 258 /** 259 Perform an explicit conversion. 260 */ 261 template <class T> 262 T cast () const 263 { 264 StackPop p (m_L, 1); 265 push (m_L); 266 267 // lua_gettop is used because Userdata::getClass() doesn't handle 268 // negative stack indexes. 269 // 270 return Stack <T>::get (m_L, lua_gettop (m_L)); 271 } 272 273 //-------------------------------------------------------------------------- 274 /** 275 Universal implicit conversion operator. 276 277 NOTE: Visual Studio 2010 and 2012 have a bug where this function 278 is not used. See: 279 280 http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/e30b2664-a92d-445c-9db2-e8e0fbde2014 281 https://connect.microsoft.com/VisualStudio/feedback/details/771509/correct-code-doesnt-compile 282 283 \code 284 // This code snippet fails to compile in vs2010,vs2012 285 struct S { 286 template <class T> inline operator T () const { return T (); } 287 }; 288 int main () { 289 S () || false; 290 return 0; 291 } 292 \endcode 293 */ 294 template <class T> 295 inline operator T () const 296 { 297 return cast <T> (); 298 } 299 300 //-------------------------------------------------------------------------- 301 /** 302 Universal comparison operators. 303 */ 304 /** @{ */ 305 template <class T> 306 bool operator== (T rhs) const 307 { 308 StackPop p (m_L, 2); 309 push (m_L); 310 Stack <T>::push (m_L, rhs); 311 return lua_compare (m_L, -2, -1, LUA_OPEQ) == 1; 312 } 313 314 template <class T> 315 bool operator< (T rhs) const 316 { 317 StackPop p (m_L, 2); 318 push (m_L); 319 Stack <T>::push (m_L, rhs); 320 return lua_compare (m_L, -2, -1, LUA_OPLT) == 1; 321 } 322 323 template <class T> 324 bool operator<= (T rhs) const 325 { 326 StackPop p (m_L, 2); 327 push (m_L); 328 Stack <T>::push (m_L, rhs); 329 return lua_compare (m_L, -2, -1, LUA_OPLE) == 1; 330 } 331 332 template <class T> 333 bool operator> (T rhs) const 334 { 335 StackPop p (m_L, 2); 336 push (m_L); 337 Stack <T>::push (m_L, rhs); 338 return lua_compare (m_L, -1, -2, LUA_OPLT) == 1; 339 } 340 341 template <class T> 342 bool operator>= (T rhs) const 343 { 344 StackPop p (m_L, 2); 345 push (m_L); 346 Stack <T>::push (m_L, rhs); 347 return lua_compare (m_L, -1, -2, LUA_OPLE) == 1; 348 } 349 350 template <class T> 351 bool rawequal (T rhs) const 352 { 353 StackPop p (m_L, 2); 354 push (m_L); 355 Stack <T>::push (m_L, rhs); 356 return lua_rawequal (m_L, -1, -2) == 1; 357 } 358 /** @} */ 359 360 //-------------------------------------------------------------------------- 361 /** 362 Access a table value using a key. 363 364 This invokes metamethods. 365 */ 366 template <class T> 367 Proxy operator[] (T key) const 368 { 369 return LuaRef (*this) [key]; 370 } 371 372 //-------------------------------------------------------------------------- 373 /** 374 Access a table value using a key. 375 376 The operation is raw, metamethods are not invoked. The result is 377 passed by value and may not be modified. 378 */ 379 template <class T> 380 LuaRef rawget (T key) const 381 { 382 StackPop (m_L, 1); 383 push (m_L); 384 Stack <T>::push (m_L, key); 385 lua_rawget (m_L, -2); 386 return LuaRef (m_L, FromStack ()); 387 } 388 389 //-------------------------------------------------------------------------- 390 /** 391 Append a value to the table. 392 393 If the table is a sequence this will add another element to it. 394 */ 395 template <class T> 396 void append (T v) const 397 { 398 push (m_L); 399 Stack <T>::push (m_L, v); 400 luaL_ref (m_L, -2); 401 lua_pop (m_L, 1); 402 } 403 404 //-------------------------------------------------------------------------- 405 /** 406 Call the length operator. 407 408 This is identical to applying the Lua # operator. 409 */ 410 int length () const 411 { 412 StackPop p (m_L, 1); 413 push (m_L); 414 return get_length (m_L, -1); 415 } 416 417 //-------------------------------------------------------------------------- 418 /** 419 Call Lua code. 420 421 These overloads allow Lua code to be called with up to 8 parameters. 422 The return value is provided as a LuaRef (which may be LUA_REFNIL). 423 If an error occurs, a LuaException is thrown. 424 */ 425 /** @{ */ 426 LuaRef const operator() () const 427 { 428 push (m_L); 429 LuaException::pcall (m_L, 0, 1); 430 return LuaRef (m_L, FromStack ()); 431 } 432 433 template <class P1> 434 LuaRef const operator() (P1 p1) const 435 { 436 push (m_L); 437 Stack <P1>::push (m_L, p1); 438 LuaException::pcall (m_L, 1, 1); 439 return LuaRef (m_L, FromStack ()); 440 } 441 442 template <class P1, class P2> 443 LuaRef const operator() (P1 p1, P2 p2) const 444 { 445 push (m_L); 446 Stack <P1>::push (m_L, p1); 447 Stack <P2>::push (m_L, p2); 448 LuaException::pcall (m_L, 2, 1); 449 return LuaRef (m_L, FromStack ()); 450 } 451 452 template <class P1, class P2, class P3> 453 LuaRef const operator() (P1 p1, P2 p2, P3 p3) const 454 { 455 push (m_L); 456 Stack <P1>::push (m_L, p1); 457 Stack <P2>::push (m_L, p2); 458 Stack <P3>::push (m_L, p3); 459 LuaException::pcall (m_L, 3, 1); 460 return LuaRef (m_L, FromStack ()); 461 } 462 463 template <class P1, class P2, class P3, class P4> 464 LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4) const 465 { 466 push (m_L); 467 Stack <P1>::push (m_L, p1); 468 Stack <P2>::push (m_L, p2); 469 Stack <P3>::push (m_L, p3); 470 Stack <P4>::push (m_L, p4); 471 LuaException::pcall (m_L, 4, 1); 472 return LuaRef (m_L, FromStack ()); 473 } 474 475 template <class P1, class P2, class P3, class P4, class P5> 476 LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const 477 { 478 push (m_L); 479 Stack <P1>::push (m_L, p1); 480 Stack <P2>::push (m_L, p2); 481 Stack <P3>::push (m_L, p3); 482 Stack <P4>::push (m_L, p4); 483 Stack <P5>::push (m_L, p5); 484 LuaException::pcall (m_L, 5, 1); 485 return LuaRef (m_L, FromStack ()); 486 } 487 488 template <class P1, class P2, class P3, class P4, class P5, class P6> 489 LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) const 490 { 491 push (m_L); 492 Stack <P1>::push (m_L, p1); 493 Stack <P2>::push (m_L, p2); 494 Stack <P3>::push (m_L, p3); 495 Stack <P4>::push (m_L, p4); 496 Stack <P5>::push (m_L, p5); 497 Stack <P6>::push (m_L, p6); 498 LuaException::pcall (m_L, 6, 1); 499 return LuaRef (m_L, FromStack ()); 500 } 501 502 template <class P1, class P2, class P3, class P4, class P5, class P6, class P7> 503 LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) const 504 { 505 push (m_L); 506 Stack <P1>::push (m_L, p1); 507 Stack <P2>::push (m_L, p2); 508 Stack <P3>::push (m_L, p3); 509 Stack <P4>::push (m_L, p4); 510 Stack <P5>::push (m_L, p5); 511 Stack <P6>::push (m_L, p6); 512 Stack <P7>::push (m_L, p7); 513 LuaException::pcall (m_L, 7, 1); 514 return LuaRef (m_L, FromStack ()); 515 } 516 517 template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8> 518 LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) const 519 { 520 push (m_L); 521 Stack <P1>::push (m_L, p1); 522 Stack <P2>::push (m_L, p2); 523 Stack <P3>::push (m_L, p3); 524 Stack <P4>::push (m_L, p4); 525 Stack <P5>::push (m_L, p5); 526 Stack <P6>::push (m_L, p6); 527 Stack <P7>::push (m_L, p7); 528 Stack <P8>::push (m_L, p8); 529 LuaException::pcall (m_L, 8, 1); 530 return LuaRef (m_L, FromStack ()); 531 } 532 /** @} */ 533 534 //========================================================================== 535 }; 536 537 private: 538 friend struct Stack <LuaRef>; 539 540 //---------------------------------------------------------------------------- 541 /** 542 Type tag for stack construction. 543 */ 544 struct FromStack { }; 545 546 //---------------------------------------------------------------------------- 547 /** 548 Create a reference to an object at the top of the Lua stack and pop it. 549 550 This constructor is private and not invoked directly. 551 Instead, use the `fromStack` function. 552 553 @note The object is popped. 554 */ 555 LuaRef (lua_State* L, FromStack) 556 : m_L (L) 557 { 558 m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX); 559 } 560 561 //---------------------------------------------------------------------------- 562 /** 563 Create a reference to an object on the Lua stack. 564 565 This constructor is private and not invoked directly. 566 Instead, use the `fromStack` function. 567 568 @note The object is not popped. 569 */ 570 LuaRef (lua_State* L, int index, FromStack) 571 : m_L (L) 572 { 573 lua_pushvalue (m_L, index); 574 m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX); 575 } 576 577 //---------------------------------------------------------------------------- 578 579 // This type of construction is disallowed, since we don't have a `lua_State`. 580 // 581 template <class T> 582 LuaRef (T) 583 { 584 } 585 586 //---------------------------------------------------------------------------- 587 /** 588 Create a reference to this ref. 589 590 This is used internally. 591 */ 592 int createRef () const 593 { 594 if (m_ref != LUA_REFNIL) 595 { 596 push (m_L); 597 return luaL_ref (m_L, LUA_REGISTRYINDEX); 598 } 599 else 600 { 601 return LUA_REFNIL; 602 } 603 } 604 605 public: 606 //---------------------------------------------------------------------------- 607 /** 608 Create a nil reference. 609 610 The LuaRef may be assigned later. 611 */ 612 LuaRef (lua_State* L) 613 : m_L (L) 614 , m_ref (LUA_REFNIL) 615 { 616 } 617 618 //---------------------------------------------------------------------------- 619 /** 620 Create a reference to a value. 621 */ 622 template <class T> 623 LuaRef (lua_State* L, T v) 624 : m_L (L) 625 { 626 Stack <T>::push (m_L, v); 627 m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX); 628 } 629 630 //---------------------------------------------------------------------------- 631 /** 632 Create a reference to a table value. 633 */ 634 LuaRef (Proxy const& v) 635 : m_L (v.state ()) 636 , m_ref (v.createRef ()) 637 { 638 } 639 640 //---------------------------------------------------------------------------- 641 /** 642 Create a new reference to an existing reference. 643 */ 644 LuaRef (LuaRef const& other) 645 : m_L (other.m_L) 646 , m_ref (other.createRef ()) 647 { 648 } 649 650 //---------------------------------------------------------------------------- 651 /** 652 Destroy a reference. 653 654 The corresponding Lua registry reference will be released. 655 656 @note If the state refers to a thread, it is the responsibility of the 657 caller to ensure that the thread still exists when the LuaRef 658 is destroyed. 659 */ 660 ~LuaRef () 661 { 662 luaL_unref (m_L, LUA_REGISTRYINDEX, m_ref); 663 } 664 665 //---------------------------------------------------------------------------- 666 /** 667 Return a LuaRef from a stack item. 668 669 The stack item is not popped. 670 */ 671 static LuaRef fromStack (lua_State* L, int index) 672 { 673 lua_pushvalue (L, index); 674 return LuaRef (L, FromStack ()); 675 } 676 677 //---------------------------------------------------------------------------- 678 /** 679 Create a new empty table and return a reference to it. 680 681 It is also possible to use the free function `newTable`. 682 683 @see ::getGlobal 684 */ 685 static LuaRef newTable (lua_State* L) 686 { 687 lua_newtable (L); 688 return LuaRef (L, FromStack ()); 689 } 690 691 //---------------------------------------------------------------------------- 692 /** 693 Return a reference to a named global. 694 695 It is also possible to use the free function `getGlobal`. 696 697 @see ::getGlobal 698 */ 699 static LuaRef getGlobal (lua_State *L, char const* name) 700 { 701 lua_getglobal (L, name); 702 return LuaRef (L, FromStack ()); 703 } 704 705 //---------------------------------------------------------------------------- 706 /** 707 Assign a different value to this LuaRef. 708 */ 709 template <class T> 710 LuaRef& operator= (T rhs) 711 { 712 luaL_unref (m_L, LUA_REGISTRYINDEX, m_ref); 713 Stack <T>::push (m_L, rhs); 714 m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX); 715 return *this; 716 } 717 718 //---------------------------------------------------------------------------- 719 /** 720 Assign another LuaRef to this LuaRef. 721 */ 722 LuaRef& operator= (LuaRef const& rhs) 723 { 724 luaL_unref (m_L, LUA_REGISTRYINDEX, m_ref); 725 rhs.push (m_L); 726 m_L = rhs.state (); 727 m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX); 728 return *this; 729 } 730 731 //---------------------------------------------------------------------------- 732 /** 733 converts to a string using luas tostring function 734 */ 735 std::string tostring() const 736 { 737 lua_getglobal (m_L, "tostring"); 738 push (m_L); 739 lua_call (m_L, 1, 1); 740 const char* str = lua_tostring(m_L, 1); 741 lua_pop(m_L, 1); 742 return std::string(str); 743 } 744 745 //---------------------------------------------------------------------------- 746 /** 747 Print a text description of the value to a stream. 748 749 This is used for diagnostics. 750 */ 751 void print (std::ostream& os) const 752 { 753 switch (type ()) 754 { 755 case LUA_TNIL: 756 os << "nil"; 757 break; 758 759 case LUA_TNUMBER: 760 os << cast <lua_Number> (); 761 break; 762 763 case LUA_TBOOLEAN: 764 os << (cast <bool> () ? "true" : "false"); 765 break; 766 767 case LUA_TSTRING: 768 os << '"' << cast <std::string> () << '"'; 769 break; 770 771 case LUA_TTABLE: 772 os << "table: " << tostring(); 773 break; 774 775 case LUA_TFUNCTION: 776 os << "function: " << tostring(); 777 break; 778 779 case LUA_TUSERDATA: 780 os << "userdata: " << tostring(); 781 break; 782 783 case LUA_TTHREAD: 784 os << "thread: " << tostring(); 785 break; 786 787 case LUA_TLIGHTUSERDATA: 788 os << "lightuserdata: " << tostring(); 789 break; 790 791 default: 792 os << "unknown"; 793 break; 794 } 795 } 796 797 //============================================================================ 798 // 799 // This group of member functions is mirrored in Proxy 800 // 801 802 /** Retrieve the lua_State associated with the reference. 803 */ 804 lua_State* state () const 805 { 806 return m_L; 807 } 808 809 //---------------------------------------------------------------------------- 810 /** 811 Place the object onto the Lua stack. 812 */ 813 void push (lua_State* L) const 814 { 815 assert (equalstates (L, m_L)); 816 lua_rawgeti (L, LUA_REGISTRYINDEX, m_ref); 817 } 818 819 //---------------------------------------------------------------------------- 820 /** 821 Pop the top of Lua stack and assign the ref to m_ref 822 */ 823 void pop (lua_State* L) 824 { 825 assert (equalstates (L, m_L)); 826 luaL_unref (m_L, LUA_REGISTRYINDEX, m_ref); 827 m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX); 828 } 829 830 //---------------------------------------------------------------------------- 831 /** 832 Determine the object type. 833 834 The return values are the same as for `lua_type`. 835 */ 836 /** @{ */ 837 int type () const 838 { 839 int result; 840 if (m_ref != LUA_REFNIL) 841 { 842 push (m_L); 843 result = lua_type (m_L, -1); 844 lua_pop (m_L, 1); 845 } 846 else 847 { 848 result = LUA_TNIL; 849 } 850 851 return result; 852 } 853 854 // should never happen 855 //inline bool isNone () const { return m_ref == LUA_NOREF; } 856 857 inline bool isNil () const { return type () == LUA_TNIL; } 858 inline bool isBoolean () const { return type () == LUA_TBOOLEAN; } 859 inline bool isNumber () const { return type () == LUA_TNUMBER; } 860 inline bool isString () const { return type () == LUA_TSTRING; } 861 inline bool isTable () const { return type () == LUA_TTABLE; } 862 inline bool isFunction () const { return type () == LUA_TFUNCTION; } 863 inline bool isUserdata () const { return type () == LUA_TUSERDATA; } 864 inline bool isThread () const { return type () == LUA_TTHREAD; } 865 inline bool isLightUserdata () const { return type () == LUA_TLIGHTUSERDATA; } 866 /** @} */ 867 868 //---------------------------------------------------------------------------- 869 /** 870 Perform an explicit conversion. 871 */ 872 template <class T> 873 T cast () const 874 { 875 StackPop p (m_L, 1); 876 push (m_L); 877 878 // lua_gettop is used because Userdata::getClass() doesn't handle 879 // negative stack indexes. 880 // 881 return Stack <T>::get (m_L, lua_gettop (m_L)); 882 } 883 884 //---------------------------------------------------------------------------- 885 /** 886 Universal implicit conversion operator. 887 888 NOTE: Visual Studio 2010 and 2012 have a bug where this function 889 is not used. See: 890 891 http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/e30b2664-a92d-445c-9db2-e8e0fbde2014 892 https://connect.microsoft.com/VisualStudio/feedback/details/771509/correct-code-doesnt-compile 893 894 \code 895 // This code snippet fails to compile in vs2010,vs2012 896 struct S { 897 template <class T> inline operator T () const { return T (); } 898 }; 899 int main () { 900 S () || false; 901 return 0; 902 } 903 \endcode 904 */ 905 template <class T> 906 inline operator T () const 907 { 908 return cast <T> (); 909 } 910 911 //---------------------------------------------------------------------------- 912 /** 913 Universal comparison operators. 914 */ 915 /** @{ */ 916 template <class T> 917 bool operator== (T rhs) const 918 { 919 StackPop p (m_L, 2); 920 push (m_L); 921 Stack <T>::push (m_L, rhs); 922 return lua_compare (m_L, -2, -1, LUA_OPEQ) == 1; 923 } 924 925 template <class T> 926 bool operator< (T rhs) const 927 { 928 StackPop p (m_L, 2); 929 push (m_L); 930 Stack <T>::push (m_L, rhs); 931 return lua_compare (m_L, -2, -1, LUA_OPLT) == 1; 932 } 933 934 template <class T> 935 bool operator<= (T rhs) const 936 { 937 StackPop p (m_L, 2); 938 push (m_L); 939 Stack <T>::push (m_L, rhs); 940 return lua_compare (m_L, -2, -1, LUA_OPLE) == 1; 941 } 942 943 template <class T> 944 bool operator> (T rhs) const 945 { 946 StackPop p (m_L, 2); 947 push (m_L); 948 Stack <T>::push (m_L, rhs); 949 return lua_compare (m_L, -1, -2, LUA_OPLT) == 1; 950 } 951 952 template <class T> 953 bool operator>= (T rhs) const 954 { 955 StackPop p (m_L, 2); 956 push (m_L); 957 Stack <T>::push (m_L, rhs); 958 return lua_compare (m_L, -1, -2, LUA_OPLE) == 1; 959 } 960 961 template <class T> 962 bool rawequal (T rhs) const 963 { 964 StackPop p (m_L, 2); 965 push (m_L); 966 Stack <T>::push (m_L, rhs); 967 return lua_rawequal (m_L, -1, -2) == 1; 968 } 969 /** @} */ 970 971 //---------------------------------------------------------------------------- 972 /** 973 Append a value to the table. 974 975 If the table is a sequence this will add another element to it. 976 */ 977 template <class T> 978 void append (T v) const 979 { 980 push (m_L); 981 Stack <T>::push (m_L, v); 982 luaL_ref (m_L, -2); 983 lua_pop (m_L, 1); 984 } 985 986 //---------------------------------------------------------------------------- 987 /** 988 Call the length operator. 989 990 This is identical to applying the Lua # operator. 991 */ 992 int length () const 993 { 994 StackPop p (m_L, 1); 995 push (m_L); 996 return get_length (m_L, -1); 997 } 998 999 //---------------------------------------------------------------------------- 1000 /** 1001 Access a table value using a key. 1002 1003 This invokes metamethods. 1004 */ 1005 template <class T> 1006 Proxy operator[] (T key) const 1007 { 1008 Stack <T>::push (m_L, key); 1009 return Proxy (m_L, m_ref); 1010 } 1011 1012 //---------------------------------------------------------------------------- 1013 /** 1014 Call Lua code. 1015 1016 These overloads allow Lua code to be called with up to 8 parameters. 1017 The return value is provided as a LuaRef (which may be LUA_REFNIL). 1018 If an error occurs, a LuaException is thrown. 1019 */ 1020 /** @{ */ 1021 LuaRef const operator() () const 1022 { 1023 push (m_L); 1024 LuaException::pcall (m_L, 0, 1); 1025 return LuaRef (m_L, FromStack ()); 1026 } 1027 1028 template <class P1> 1029 LuaRef const operator() (P1 p1) const 1030 { 1031 push (m_L); 1032 Stack <P1>::push (m_L, p1); 1033 LuaException::pcall (m_L, 1, 1); 1034 return LuaRef (m_L, FromStack ()); 1035 } 1036 1037 template <class P1, class P2> 1038 LuaRef const operator() (P1 p1, P2 p2) const 1039 { 1040 push (m_L); 1041 Stack <P1>::push (m_L, p1); 1042 Stack <P2>::push (m_L, p2); 1043 LuaException::pcall (m_L, 2, 1); 1044 return LuaRef (m_L, FromStack ()); 1045 } 1046 1047 template <class P1, class P2, class P3> 1048 LuaRef const operator() (P1 p1, P2 p2, P3 p3) const 1049 { 1050 push (m_L); 1051 Stack <P1>::push (m_L, p1); 1052 Stack <P2>::push (m_L, p2); 1053 Stack <P3>::push (m_L, p3); 1054 LuaException::pcall (m_L, 3, 1); 1055 return LuaRef (m_L, FromStack ()); 1056 } 1057 1058 template <class P1, class P2, class P3, class P4> 1059 LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4) const 1060 { 1061 push (m_L); 1062 Stack <P1>::push (m_L, p1); 1063 Stack <P2>::push (m_L, p2); 1064 Stack <P3>::push (m_L, p3); 1065 Stack <P4>::push (m_L, p4); 1066 LuaException::pcall (m_L, 4, 1); 1067 return LuaRef (m_L, FromStack ()); 1068 } 1069 1070 template <class P1, class P2, class P3, class P4, class P5> 1071 LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const 1072 { 1073 push (m_L); 1074 Stack <P1>::push (m_L, p1); 1075 Stack <P2>::push (m_L, p2); 1076 Stack <P3>::push (m_L, p3); 1077 Stack <P4>::push (m_L, p4); 1078 Stack <P5>::push (m_L, p5); 1079 LuaException::pcall (m_L, 5, 1); 1080 return LuaRef (m_L, FromStack ()); 1081 } 1082 1083 template <class P1, class P2, class P3, class P4, class P5, class P6> 1084 LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) const 1085 { 1086 push (m_L); 1087 Stack <P1>::push (m_L, p1); 1088 Stack <P2>::push (m_L, p2); 1089 Stack <P3>::push (m_L, p3); 1090 Stack <P4>::push (m_L, p4); 1091 Stack <P5>::push (m_L, p5); 1092 Stack <P6>::push (m_L, p6); 1093 LuaException::pcall (m_L, 6, 1); 1094 return LuaRef (m_L, FromStack ()); 1095 } 1096 1097 template <class P1, class P2, class P3, class P4, class P5, class P6, class P7> 1098 LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) const 1099 { 1100 push (m_L); 1101 Stack <P1>::push (m_L, p1); 1102 Stack <P2>::push (m_L, p2); 1103 Stack <P3>::push (m_L, p3); 1104 Stack <P4>::push (m_L, p4); 1105 Stack <P5>::push (m_L, p5); 1106 Stack <P6>::push (m_L, p6); 1107 Stack <P7>::push (m_L, p7); 1108 LuaException::pcall (m_L, 7, 1); 1109 return LuaRef (m_L, FromStack ()); 1110 } 1111 1112 template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8> 1113 LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) const 1114 { 1115 push (m_L); 1116 Stack <P1>::push (m_L, p1); 1117 Stack <P2>::push (m_L, p2); 1118 Stack <P3>::push (m_L, p3); 1119 Stack <P4>::push (m_L, p4); 1120 Stack <P5>::push (m_L, p5); 1121 Stack <P6>::push (m_L, p6); 1122 Stack <P7>::push (m_L, p7); 1123 Stack <P8>::push (m_L, p8); 1124 LuaException::pcall (m_L, 8, 1); 1125 return LuaRef (m_L, FromStack ()); 1126 } 1127 /** @} */ 1128 1129 //============================================================================ 1130 1131 private: 1132 lua_State* m_L; 1133 int m_ref; 1134 }; 1135 1136 //------------------------------------------------------------------------------ 1137 /** 1138 Stack specialization for Nil 1139 */ 1140 template <> 1141 struct Stack <Nil> 1142 { 1143 public: 1144 static inline void push (lua_State* L, Nil) 1145 { 1146 lua_pushnil (L); 1147 } 1148 }; 1149 1150 //------------------------------------------------------------------------------ 1151 /** 1152 Stack specialization for LuaRef. 1153 */ 1154 template <> 1155 struct Stack <LuaRef> 1156 { 1157 public: 1158 // The value is const& to prevent a copy construction. 1159 // 1160 static inline void push (lua_State* L, LuaRef const& v) 1161 { 1162 v.push (L); 1163 } 1164 1165 static inline LuaRef get (lua_State* L, int index) 1166 { 1167 return LuaRef (L, index, LuaRef::FromStack ()); 1168 } 1169 }; 1170 1171 //------------------------------------------------------------------------------ 1172 /** 1173 Stack specialization for Proxy. 1174 */ 1175 template <> 1176 struct Stack <LuaRef::Proxy> 1177 { 1178 public: 1179 // The value is const& to prevent a copy construction. 1180 // 1181 static inline void push (lua_State* L, LuaRef::Proxy const& v) 1182 { 1183 v.push (L); 1184 } 1185 }; 1186 1187 //------------------------------------------------------------------------------ 1188 /** 1189 Create a reference to a new, empty table. 1190 1191 This is a syntactic abbreviation for LuaRef::newTable(). 1192 */ 1193 inline LuaRef newTable (lua_State* L) 1194 { 1195 return LuaRef::newTable (L); 1196 } 1197 1198 //------------------------------------------------------------------------------ 1199 /** 1200 Create a reference to a value in the global table. 1201 1202 This is a syntactic abbreviation for LuaRef::getGlobal(). 1203 */ 1204 inline LuaRef getGlobal (lua_State *L, char const* name) 1205 { 1206 return LuaRef::getGlobal (L, name); 1207 } 1208 1209 //------------------------------------------------------------------------------ 1210 /** 1211 Write a LuaRef to a stream. 1212 1213 This allows LuaRef and table proxies to work with streams. 1214 */ 1215 inline std::ostream& operator<< (std::ostream& os, LuaRef const& ref) 1216 { 1217 ref.print (os); 1218 return os; 1219 } 1220 1221 //------------------------------------------------------------------------------ 1222 1223 // more C++-like cast syntax 1224 // 1225 template<class T> 1226 inline T LuaRef_cast(LuaRef const& lr) 1227 { 1228 return lr.cast<T>(); 1229 } 1230