variadic_args.hpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. // sol2
  2. // The MIT License (MIT)
  3. // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy of
  5. // this software and associated documentation files (the "Software"), to deal in
  6. // the Software without restriction, including without limitation the rights to
  7. // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  8. // the Software, and to permit persons to whom the Software is furnished to do so,
  9. // subject to the following conditions:
  10. // The above copyright notice and this permission notice shall be included in all
  11. // copies or substantial portions of the Software.
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  14. // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  15. // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  16. // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  17. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  18. #ifndef SOL_VARIADIC_ARGS_HPP
  19. #define SOL_VARIADIC_ARGS_HPP
  20. #include <sol/stack.hpp>
  21. #include <sol/stack_proxy.hpp>
  22. #include <sol/stack_iterator.hpp>
  23. #include <limits>
  24. #include <iterator>
  25. namespace sol {
  26. struct variadic_args {
  27. private:
  28. lua_State* L;
  29. int index;
  30. int stacktop;
  31. public:
  32. typedef stack_proxy reference_type;
  33. typedef stack_proxy value_type;
  34. typedef stack_proxy* pointer;
  35. typedef std::ptrdiff_t difference_type;
  36. typedef std::size_t size_type;
  37. typedef stack_iterator<stack_proxy, false> iterator;
  38. typedef stack_iterator<stack_proxy, true> const_iterator;
  39. typedef std::reverse_iterator<iterator> reverse_iterator;
  40. typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
  41. variadic_args() = default;
  42. variadic_args(lua_State* luastate, int stackindex = -1) : L(luastate), index(lua_absindex(luastate, stackindex)), stacktop(lua_gettop(luastate)) {
  43. }
  44. variadic_args(lua_State* luastate, int stackindex, int lastindex) : L(luastate), index(lua_absindex(luastate, stackindex)), stacktop(lastindex) {
  45. }
  46. variadic_args(const variadic_args&) = default;
  47. variadic_args& operator=(const variadic_args&) = default;
  48. variadic_args(variadic_args&& o) : L(o.L), index(o.index), stacktop(o.stacktop) {
  49. // Must be manual, otherwise destructor will screw us
  50. // return count being 0 is enough to keep things clean
  51. // but will be thorough
  52. o.L = nullptr;
  53. o.index = 0;
  54. o.stacktop = 0;
  55. }
  56. variadic_args& operator=(variadic_args&& o) {
  57. L = o.L;
  58. index = o.index;
  59. stacktop = o.stacktop;
  60. // Must be manual, otherwise destructor will screw us
  61. // return count being 0 is enough to keep things clean
  62. // but will be thorough
  63. o.L = nullptr;
  64. o.index = 0;
  65. o.stacktop = 0;
  66. return *this;
  67. }
  68. iterator begin() {
  69. return iterator(L, index, stacktop + 1);
  70. }
  71. iterator end() {
  72. return iterator(L, stacktop + 1, stacktop + 1);
  73. }
  74. const_iterator begin() const {
  75. return const_iterator(L, index, stacktop + 1);
  76. }
  77. const_iterator end() const {
  78. return const_iterator(L, stacktop + 1, stacktop + 1);
  79. }
  80. const_iterator cbegin() const {
  81. return begin();
  82. }
  83. const_iterator cend() const {
  84. return end();
  85. }
  86. reverse_iterator rbegin() {
  87. return std::reverse_iterator<iterator>(begin());
  88. }
  89. reverse_iterator rend() {
  90. return std::reverse_iterator<iterator>(end());
  91. }
  92. const_reverse_iterator rbegin() const {
  93. return std::reverse_iterator<const_iterator>(begin());
  94. }
  95. const_reverse_iterator rend() const {
  96. return std::reverse_iterator<const_iterator>(end());
  97. }
  98. const_reverse_iterator crbegin() const {
  99. return std::reverse_iterator<const_iterator>(cbegin());
  100. }
  101. const_reverse_iterator crend() const {
  102. return std::reverse_iterator<const_iterator>(cend());
  103. }
  104. int push() const {
  105. return push(L);
  106. }
  107. int push(lua_State* target) const {
  108. int pushcount = 0;
  109. for (int i = index; i <= stacktop; ++i) {
  110. lua_pushvalue(L, i);
  111. pushcount += 1;
  112. }
  113. if (target != L) {
  114. lua_xmove(L, target, pushcount);
  115. }
  116. return pushcount;
  117. }
  118. template <typename T>
  119. decltype(auto) get(difference_type index_offset = 0) const {
  120. return stack::get<T>(L, index + static_cast<int>(index_offset));
  121. }
  122. type get_type(difference_type index_offset = 0) const noexcept {
  123. return type_of(L, index + static_cast<int>(index_offset));
  124. }
  125. stack_proxy operator[](difference_type index_offset) const {
  126. return stack_proxy(L, index + static_cast<int>(index_offset));
  127. }
  128. lua_State* lua_state() const {
  129. return L;
  130. };
  131. int stack_index() const {
  132. return index;
  133. };
  134. int leftover_count() const {
  135. return stacktop - (index - 1);
  136. }
  137. std::size_t size() const {
  138. return static_cast<std::size_t>(leftover_count());
  139. }
  140. int top() const {
  141. return stacktop;
  142. }
  143. };
  144. namespace stack {
  145. template <>
  146. struct unqualified_getter<variadic_args> {
  147. static variadic_args get(lua_State* L, int index, record& tracking) {
  148. tracking.last = 0;
  149. return variadic_args(L, index);
  150. }
  151. };
  152. template <>
  153. struct unqualified_pusher<variadic_args> {
  154. static int push(lua_State* L, const variadic_args& ref) {
  155. return ref.push(L);
  156. }
  157. };
  158. } // namespace stack
  159. } // namespace sol
  160. #endif // SOL_VARIADIC_ARGS_HPP