bind_traits.hpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  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_BIND_TRAITS_HPP
  19. #define SOL_BIND_TRAITS_HPP
  20. #include <sol/forward.hpp>
  21. #include <sol/base_traits.hpp>
  22. #include <sol/tuple.hpp>
  23. namespace sol { namespace meta {
  24. namespace meta_detail {
  25. template <typename F>
  26. using detect_deducible_signature = decltype(&F::operator());
  27. } // namespace meta_detail
  28. template <typename F>
  29. using call_operator_deducible = typename is_detected<meta_detail::detect_deducible_signature, F>::type;
  30. template <typename F>
  31. constexpr inline bool call_operator_deducible_v = call_operator_deducible<F>::value;
  32. namespace meta_detail {
  33. template <std::size_t I, typename T>
  34. struct void_tuple_element : meta::tuple_element<I, T> { };
  35. template <std::size_t I>
  36. struct void_tuple_element<I, std::tuple<>> {
  37. typedef void type;
  38. };
  39. template <std::size_t I, typename T>
  40. using void_tuple_element_t = typename void_tuple_element<I, T>::type;
  41. template <bool it_is_noexcept, bool has_c_variadic, typename T, typename R, typename... Args>
  42. struct basic_traits {
  43. private:
  44. using first_type = meta::conditional_t<std::is_void<T>::value, int, T>&;
  45. public:
  46. inline static constexpr const bool is_noexcept = it_is_noexcept;
  47. inline static constexpr bool is_member_function = std::is_void<T>::value;
  48. inline static constexpr bool has_c_var_arg = has_c_variadic;
  49. inline static constexpr std::size_t arity = sizeof...(Args);
  50. inline static constexpr std::size_t free_arity = sizeof...(Args) + static_cast<std::size_t>(!std::is_void<T>::value);
  51. typedef types<Args...> args_list;
  52. typedef std::tuple<Args...> args_tuple;
  53. typedef T object_type;
  54. typedef R return_type;
  55. typedef tuple_types<R> returns_list;
  56. typedef R(function_type)(Args...);
  57. typedef meta::conditional_t<std::is_void<T>::value, args_list, types<first_type, Args...>> free_args_list;
  58. typedef meta::conditional_t<std::is_void<T>::value, R(Args...), R(first_type, Args...)> free_function_type;
  59. typedef meta::conditional_t<std::is_void<T>::value, R (*)(Args...), R (*)(first_type, Args...)> free_function_pointer_type;
  60. typedef std::remove_pointer_t<free_function_pointer_type> signature_type;
  61. template <std::size_t i>
  62. using arg_at = void_tuple_element_t<i, args_tuple>;
  63. };
  64. template <typename Signature, bool b = call_operator_deducible<Signature>::value>
  65. struct fx_traits : public basic_traits<false, false, void, void> { };
  66. // Free Functions
  67. template <typename R, typename... Args>
  68. struct fx_traits<R(Args...), false> : public basic_traits<false, false, void, R, Args...> {
  69. typedef R (*function_pointer_type)(Args...);
  70. };
  71. template <typename R, typename... Args>
  72. struct fx_traits<R (*)(Args...), false> : public basic_traits<false, false, void, R, Args...> {
  73. typedef R (*function_pointer_type)(Args...);
  74. };
  75. template <typename R, typename... Args>
  76. struct fx_traits<R(Args..., ...), false> : public basic_traits<false, true, void, R, Args...> {
  77. typedef R (*function_pointer_type)(Args..., ...);
  78. };
  79. template <typename R, typename... Args>
  80. struct fx_traits<R (*)(Args..., ...), false> : public basic_traits<false, true, void, R, Args...> {
  81. typedef R (*function_pointer_type)(Args..., ...);
  82. };
  83. // Member Functions
  84. /* C-Style Variadics */
  85. template <typename T, typename R, typename... Args>
  86. struct fx_traits<R (T::*)(Args...), false> : public basic_traits<false, false, T, R, Args...> {
  87. typedef R (T::*function_pointer_type)(Args...);
  88. };
  89. template <typename T, typename R, typename... Args>
  90. struct fx_traits<R (T::*)(Args..., ...), false> : public basic_traits<false, true, T, R, Args...> {
  91. typedef R (T::*function_pointer_type)(Args..., ...);
  92. };
  93. /* Const Volatile */
  94. template <typename T, typename R, typename... Args>
  95. struct fx_traits<R (T::*)(Args...) const, false> : public basic_traits<false, false, T, R, Args...> {
  96. typedef R (T::*function_pointer_type)(Args...) const;
  97. };
  98. template <typename T, typename R, typename... Args>
  99. struct fx_traits<R (T::*)(Args..., ...) const, false> : public basic_traits<false, true, T, R, Args...> {
  100. typedef R (T::*function_pointer_type)(Args..., ...) const;
  101. };
  102. template <typename T, typename R, typename... Args>
  103. struct fx_traits<R (T::*)(Args...) const volatile, false> : public basic_traits<false, false, T, R, Args...> {
  104. typedef R (T::*function_pointer_type)(Args...) const volatile;
  105. };
  106. template <typename T, typename R, typename... Args>
  107. struct fx_traits<R (T::*)(Args..., ...) const volatile, false> : public basic_traits<false, true, T, R, Args...> {
  108. typedef R (T::*function_pointer_type)(Args..., ...) const volatile;
  109. };
  110. /* Member Function Qualifiers */
  111. template <typename T, typename R, typename... Args>
  112. struct fx_traits<R (T::*)(Args...)&, false> : public basic_traits<false, false, T, R, Args...> {
  113. typedef R (T::*function_pointer_type)(Args...) &;
  114. };
  115. template <typename T, typename R, typename... Args>
  116. struct fx_traits<R (T::*)(Args..., ...)&, false> : public basic_traits<false, true, T, R, Args...> {
  117. typedef R (T::*function_pointer_type)(Args..., ...) &;
  118. };
  119. template <typename T, typename R, typename... Args>
  120. struct fx_traits<R (T::*)(Args...) const&, false> : public basic_traits<false, false, T, R, Args...> {
  121. typedef R (T::*function_pointer_type)(Args...) const&;
  122. };
  123. template <typename T, typename R, typename... Args>
  124. struct fx_traits<R (T::*)(Args..., ...) const&, false> : public basic_traits<false, true, T, R, Args...> {
  125. typedef R (T::*function_pointer_type)(Args..., ...) const&;
  126. };
  127. template <typename T, typename R, typename... Args>
  128. struct fx_traits<R (T::*)(Args...) const volatile&, false> : public basic_traits<false, false, T, R, Args...> {
  129. typedef R (T::*function_pointer_type)(Args...) const volatile&;
  130. };
  131. template <typename T, typename R, typename... Args>
  132. struct fx_traits<R (T::*)(Args..., ...) const volatile&, false> : public basic_traits<false, true, T, R, Args...> {
  133. typedef R (T::*function_pointer_type)(Args..., ...) const volatile&;
  134. };
  135. template <typename T, typename R, typename... Args>
  136. struct fx_traits<R (T::*)(Args...)&&, false> : public basic_traits<false, false, T, R, Args...> {
  137. typedef R (T::*function_pointer_type)(Args...) &&;
  138. };
  139. template <typename T, typename R, typename... Args>
  140. struct fx_traits<R (T::*)(Args..., ...)&&, false> : public basic_traits<false, true, T, R, Args...> {
  141. typedef R (T::*function_pointer_type)(Args..., ...) &&;
  142. };
  143. template <typename T, typename R, typename... Args>
  144. struct fx_traits<R (T::*)(Args...) const&&, false> : public basic_traits<false, false, T, R, Args...> {
  145. typedef R (T::*function_pointer_type)(Args...) const&&;
  146. };
  147. template <typename T, typename R, typename... Args>
  148. struct fx_traits<R (T::*)(Args..., ...) const&&, false> : public basic_traits<false, true, T, R, Args...> {
  149. typedef R (T::*function_pointer_type)(Args..., ...) const&&;
  150. };
  151. template <typename T, typename R, typename... Args>
  152. struct fx_traits<R (T::*)(Args...) const volatile&&, false> : public basic_traits<false, false, T, R, Args...> {
  153. typedef R (T::*function_pointer_type)(Args...) const volatile&&;
  154. };
  155. template <typename T, typename R, typename... Args>
  156. struct fx_traits<R (T::*)(Args..., ...) const volatile&&, false> : public basic_traits<false, true, T, R, Args...> {
  157. typedef R (T::*function_pointer_type)(Args..., ...) const volatile&&;
  158. };
  159. #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
  160. template <typename R, typename... Args>
  161. struct fx_traits<R(Args...) noexcept, false> : public basic_traits<true, false, void, R, Args...> {
  162. typedef R (*function_pointer_type)(Args...) noexcept;
  163. };
  164. template <typename R, typename... Args>
  165. struct fx_traits<R (*)(Args...) noexcept, false> : public basic_traits<true, false, void, R, Args...> {
  166. typedef R (*function_pointer_type)(Args...) noexcept;
  167. };
  168. template <typename R, typename... Args>
  169. struct fx_traits<R(Args..., ...) noexcept, false> : public basic_traits<true, true, void, R, Args...> {
  170. typedef R (*function_pointer_type)(Args..., ...) noexcept;
  171. };
  172. template <typename R, typename... Args>
  173. struct fx_traits<R (*)(Args..., ...) noexcept, false> : public basic_traits<true, true, void, R, Args...> {
  174. typedef R (*function_pointer_type)(Args..., ...) noexcept;
  175. };
  176. template <typename T, typename R, typename... Args>
  177. struct fx_traits<R (T::*)(Args...) noexcept, false> : public basic_traits<true, false, T, R, Args...> {
  178. typedef R (T::*function_pointer_type)(Args...) noexcept;
  179. };
  180. template <typename T, typename R, typename... Args>
  181. struct fx_traits<R (T::*)(Args..., ...) noexcept, false> : public basic_traits<true, true, T, R, Args...> {
  182. typedef R (T::*function_pointer_type)(Args..., ...) noexcept;
  183. };
  184. /* Const Volatile */
  185. template <typename T, typename R, typename... Args>
  186. struct fx_traits<R (T::*)(Args...) const noexcept, false> : public basic_traits<true, false, T, R, Args...> {
  187. typedef R (T::*function_pointer_type)(Args...) const noexcept;
  188. };
  189. template <typename T, typename R, typename... Args>
  190. struct fx_traits<R (T::*)(Args..., ...) const noexcept, false> : public basic_traits<true, true, T, R, Args...> {
  191. typedef R (T::*function_pointer_type)(Args..., ...) const noexcept;
  192. };
  193. template <typename T, typename R, typename... Args>
  194. struct fx_traits<R (T::*)(Args...) const volatile noexcept, false> : public basic_traits<true, false, T, R, Args...> {
  195. typedef R (T::*function_pointer_type)(Args...) const volatile noexcept;
  196. };
  197. template <typename T, typename R, typename... Args>
  198. struct fx_traits<R (T::*)(Args..., ...) const volatile noexcept, false> : public basic_traits<true, true, T, R, Args...> {
  199. typedef R (T::*function_pointer_type)(Args..., ...) const volatile noexcept;
  200. };
  201. template <typename T, typename R, typename... Args>
  202. struct fx_traits<R (T::*)(Args...)& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
  203. typedef R (T::*function_pointer_type)(Args...) & noexcept;
  204. };
  205. template <typename T, typename R, typename... Args>
  206. struct fx_traits<R (T::*)(Args..., ...)& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
  207. typedef R (T::*function_pointer_type)(Args..., ...) & noexcept;
  208. };
  209. template <typename T, typename R, typename... Args>
  210. struct fx_traits<R (T::*)(Args...) const& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
  211. typedef R (T::*function_pointer_type)(Args...) const& noexcept;
  212. };
  213. template <typename T, typename R, typename... Args>
  214. struct fx_traits<R (T::*)(Args..., ...) const& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
  215. typedef R (T::*function_pointer_type)(Args..., ...) const& noexcept;
  216. };
  217. template <typename T, typename R, typename... Args>
  218. struct fx_traits<R (T::*)(Args...) const volatile& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
  219. typedef R (T::*function_pointer_type)(Args...) const volatile& noexcept;
  220. };
  221. template <typename T, typename R, typename... Args>
  222. struct fx_traits<R (T::*)(Args..., ...) const volatile& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
  223. typedef R (T::*function_pointer_type)(Args..., ...) const volatile& noexcept;
  224. };
  225. template <typename T, typename R, typename... Args>
  226. struct fx_traits<R (T::*)(Args...)&& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
  227. typedef R (T::*function_pointer_type)(Args...) && noexcept;
  228. };
  229. template <typename T, typename R, typename... Args>
  230. struct fx_traits<R (T::*)(Args..., ...)&& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
  231. typedef R (T::*function_pointer_type)(Args..., ...) && noexcept;
  232. };
  233. template <typename T, typename R, typename... Args>
  234. struct fx_traits<R (T::*)(Args...) const&& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
  235. typedef R (T::*function_pointer_type)(Args...) const&& noexcept;
  236. };
  237. template <typename T, typename R, typename... Args>
  238. struct fx_traits<R (T::*)(Args..., ...) const&& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
  239. typedef R (T::*function_pointer_type)(Args..., ...) const&& noexcept;
  240. };
  241. template <typename T, typename R, typename... Args>
  242. struct fx_traits<R (T::*)(Args...) const volatile&& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
  243. typedef R (T::*function_pointer_type)(Args...) const volatile&& noexcept;
  244. };
  245. template <typename T, typename R, typename... Args>
  246. struct fx_traits<R (T::*)(Args..., ...) const volatile&& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
  247. typedef R (T::*function_pointer_type)(Args..., ...) const volatile&& noexcept;
  248. };
  249. #endif // noexcept is part of a function's type
  250. #if SOL_IS_ON(SOL_COMPILER_VCXX) && SOL_IS_ON(SOL_PLATFORM_X86)
  251. template <typename R, typename... Args>
  252. struct fx_traits<R __stdcall(Args...), false> : public basic_traits<false, false, void, R, Args...> {
  253. typedef R(__stdcall* function_pointer_type)(Args...);
  254. };
  255. template <typename R, typename... Args>
  256. struct fx_traits<R(__stdcall*)(Args...), false> : public basic_traits<false, false, void, R, Args...> {
  257. typedef R(__stdcall* function_pointer_type)(Args...);
  258. };
  259. template <typename T, typename R, typename... Args>
  260. struct fx_traits<R (__stdcall T::*)(Args...), false> : public basic_traits<false, false, T, R, Args...> {
  261. typedef R (__stdcall T::*function_pointer_type)(Args...);
  262. };
  263. /* Const Volatile */
  264. template <typename T, typename R, typename... Args>
  265. struct fx_traits<R (__stdcall T::*)(Args...) const, false> : public basic_traits<false, false, T, R, Args...> {
  266. typedef R (__stdcall T::*function_pointer_type)(Args...) const;
  267. };
  268. template <typename T, typename R, typename... Args>
  269. struct fx_traits<R (__stdcall T::*)(Args...) const volatile, false> : public basic_traits<false, false, T, R, Args...> {
  270. typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile;
  271. };
  272. /* Member Function Qualifiers */
  273. template <typename T, typename R, typename... Args>
  274. struct fx_traits<R (__stdcall T::*)(Args...)&, false> : public basic_traits<false, false, T, R, Args...> {
  275. typedef R (__stdcall T::*function_pointer_type)(Args...) &;
  276. };
  277. template <typename T, typename R, typename... Args>
  278. struct fx_traits<R (__stdcall T::*)(Args...) const&, false> : public basic_traits<false, false, T, R, Args...> {
  279. typedef R (__stdcall T::*function_pointer_type)(Args...) const&;
  280. };
  281. template <typename T, typename R, typename... Args>
  282. struct fx_traits<R (__stdcall T::*)(Args...) const volatile&, false> : public basic_traits<false, false, T, R, Args...> {
  283. typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile&;
  284. };
  285. template <typename T, typename R, typename... Args>
  286. struct fx_traits<R (__stdcall T::*)(Args...)&&, false> : public basic_traits<false, false, T, R, Args...> {
  287. typedef R (__stdcall T::*function_pointer_type)(Args...) &&;
  288. };
  289. template <typename T, typename R, typename... Args>
  290. struct fx_traits<R (__stdcall T::*)(Args...) const&&, false> : public basic_traits<false, false, T, R, Args...> {
  291. typedef R (__stdcall T::*function_pointer_type)(Args...) const&&;
  292. };
  293. template <typename T, typename R, typename... Args>
  294. struct fx_traits<R (__stdcall T::*)(Args...) const volatile&&, false> : public basic_traits<false, false, T, R, Args...> {
  295. typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile&&;
  296. };
  297. #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
  298. template <typename R, typename... Args>
  299. struct fx_traits<R __stdcall(Args...) noexcept, false> : public basic_traits<true, false, void, R, Args...> {
  300. typedef R(__stdcall* function_pointer_type)(Args...) noexcept;
  301. };
  302. template <typename R, typename... Args>
  303. struct fx_traits<R(__stdcall*)(Args...) noexcept, false> : public basic_traits<true, false, void, R, Args...> {
  304. typedef R(__stdcall* function_pointer_type)(Args...) noexcept;
  305. };
  306. /* __stdcall cannot be applied to functions with varargs*/
  307. /*template <typename R, typename... Args>
  308. struct fx_traits<__stdcall R(Args..., ...) noexcept, false> : public basic_traits<true, true, void, R, Args...> {
  309. typedef R(__stdcall* function_pointer_type)(Args..., ...) noexcept;
  310. };
  311. template <typename R, typename... Args>
  312. struct fx_traits<R (__stdcall *)(Args..., ...) noexcept, false> : public basic_traits<true, true, void, R, Args...> {
  313. typedef R(__stdcall* function_pointer_type)(Args..., ...) noexcept;
  314. };*/
  315. template <typename T, typename R, typename... Args>
  316. struct fx_traits<R (__stdcall T::*)(Args...) noexcept, false> : public basic_traits<true, false, T, R, Args...> {
  317. typedef R (__stdcall T::*function_pointer_type)(Args...) noexcept;
  318. };
  319. /* __stdcall does not work with varargs */
  320. /*template <typename T, typename R, typename... Args>
  321. struct fx_traits<R (__stdcall T::*)(Args..., ...) noexcept, false> : public basic_traits<true, true, T, R, Args...> {
  322. typedef R (__stdcall T::*function_pointer_type)(Args..., ...) noexcept;
  323. };*/
  324. /* Const Volatile */
  325. template <typename T, typename R, typename... Args>
  326. struct fx_traits<R (__stdcall T::*)(Args...) const noexcept, false> : public basic_traits<true, false, T, R, Args...> {
  327. typedef R (__stdcall T::*function_pointer_type)(Args...) const noexcept;
  328. };
  329. /* __stdcall does not work with varargs */
  330. /*template <typename T, typename R, typename... Args>
  331. struct fx_traits<R (__stdcall T::*)(Args..., ...) const noexcept, false> : public basic_traits<true, true, T, R, Args...> {
  332. typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const noexcept;
  333. };*/
  334. template <typename T, typename R, typename... Args>
  335. struct fx_traits<R (__stdcall T::*)(Args...) const volatile noexcept, false> : public basic_traits<true, false, T, R, Args...> {
  336. typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile noexcept;
  337. };
  338. /* __stdcall does not work with varargs */
  339. /*template <typename T, typename R, typename... Args>
  340. struct fx_traits<R (__stdcall T::*)(Args..., ...) const volatile noexcept, false> : public basic_traits<true, true, T, R, Args...> {
  341. typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const volatile noexcept;
  342. };*/
  343. template <typename T, typename R, typename... Args>
  344. struct fx_traits<R (__stdcall T::*)(Args...)& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
  345. typedef R (__stdcall T::*function_pointer_type)(Args...) & noexcept;
  346. };
  347. /* __stdcall does not work with varargs */
  348. /*template <typename T, typename R, typename... Args>
  349. struct fx_traits<R (__stdcall T::*)(Args..., ...) & noexcept, false> : public basic_traits<true, true, T, R, Args...> {
  350. typedef R (__stdcall T::*function_pointer_type)(Args..., ...) & noexcept;
  351. };*/
  352. template <typename T, typename R, typename... Args>
  353. struct fx_traits<R (__stdcall T::*)(Args...) const& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
  354. typedef R (__stdcall T::*function_pointer_type)(Args...) const& noexcept;
  355. };
  356. /* __stdcall does not work with varargs */
  357. /*template <typename T, typename R, typename... Args>
  358. struct fx_traits<R (__stdcall T::*)(Args..., ...) const& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
  359. typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const& noexcept;
  360. };*/
  361. template <typename T, typename R, typename... Args>
  362. struct fx_traits<R (__stdcall T::*)(Args...) const volatile& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
  363. typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile& noexcept;
  364. };
  365. /* __stdcall does not work with varargs */
  366. /*template <typename T, typename R, typename... Args>
  367. struct fx_traits<R (__stdcall T::*)(Args..., ...) const volatile& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
  368. typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const volatile& noexcept;
  369. };*/
  370. template <typename T, typename R, typename... Args>
  371. struct fx_traits<R (__stdcall T::*)(Args...)&& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
  372. typedef R (__stdcall T::*function_pointer_type)(Args...) && noexcept;
  373. };
  374. /* __stdcall does not work with varargs */
  375. /*template <typename T, typename R, typename... Args>
  376. struct fx_traits<R (__stdcall T::*)(Args..., ...) && noexcept, false> : public basic_traits<true, true, T, R, Args...> {
  377. typedef R (__stdcall T::*function_pointer_type)(Args..., ...) && noexcept;
  378. };*/
  379. template <typename T, typename R, typename... Args>
  380. struct fx_traits<R (__stdcall T::*)(Args...) const&& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
  381. typedef R (__stdcall T::*function_pointer_type)(Args...) const&& noexcept;
  382. };
  383. /* __stdcall does not work with varargs */
  384. /*template <typename T, typename R, typename... Args>
  385. struct fx_traits<R (__stdcall T::*)(Args..., ...) const&& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
  386. typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const&& noexcept;
  387. };*/
  388. template <typename T, typename R, typename... Args>
  389. struct fx_traits<R (__stdcall T::*)(Args...) const volatile&& noexcept, false> : public basic_traits<true, false, T, R, Args...> {
  390. typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile&& noexcept;
  391. };
  392. /* __stdcall does not work with varargs */
  393. /*template <typename T, typename R, typename... Args>
  394. struct fx_traits<R (__stdcall T::*)(Args..., ...) const volatile&& noexcept, false> : public basic_traits<true, true, T, R, Args...> {
  395. typedef R (__stdcall T::*function_pointer_type)(Args..., ...) const volatile&& noexcept;
  396. };*/
  397. #endif // noexcept is part of a function's type
  398. #endif // __stdcall x86 VC++ bug
  399. template <typename Signature>
  400. struct fx_traits<Signature, true> : public fx_traits<typename fx_traits<decltype(&Signature::operator())>::function_type, false> { };
  401. template <typename Signature, bool b = std::is_member_object_pointer<Signature>::value>
  402. struct callable_traits : public fx_traits<std::decay_t<Signature>> { };
  403. template <typename R, typename T>
  404. struct callable_traits<R(T::*), true> {
  405. typedef meta::conditional_t<std::is_array_v<R>, std::add_lvalue_reference_t<R>, R> return_type;
  406. typedef return_type Arg;
  407. typedef T object_type;
  408. using signature_type = R(T::*);
  409. inline static constexpr bool is_noexcept = false;
  410. inline static constexpr bool is_member_function = false;
  411. inline static constexpr std::size_t arity = 1;
  412. inline static constexpr std::size_t free_arity = 2;
  413. typedef std::tuple<Arg> args_tuple;
  414. typedef types<Arg> args_list;
  415. typedef types<T, Arg> free_args_list;
  416. typedef meta::tuple_types<return_type> returns_list;
  417. typedef return_type(function_type)(T&, return_type);
  418. typedef return_type (*function_pointer_type)(T&, Arg);
  419. typedef return_type (*free_function_pointer_type)(T&, Arg);
  420. template <std::size_t i>
  421. using arg_at = void_tuple_element_t<i, args_tuple>;
  422. };
  423. } // namespace meta_detail
  424. template <typename Signature>
  425. using bind_traits = meta_detail::callable_traits<Signature>;
  426. namespace meta_detail {
  427. template <typename, bool>
  428. struct is_probably_stateless_lambda : std::false_type { };
  429. template <typename T>
  430. struct is_probably_stateless_lambda<T, true> : std::is_convertible<T, typename bind_traits<T>::function_type*>::type { };
  431. } // namespace meta_detail
  432. template <typename T>
  433. using is_probably_stateless_lambda = typename meta_detail::is_probably_stateless_lambda<T, std::is_empty_v<T> && call_operator_deducible_v<T>>::type;
  434. template <typename T>
  435. inline constexpr bool is_probably_stateless_lambda_v = is_probably_stateless_lambda<T>::value;
  436. template <typename Signature>
  437. using function_args_t = typename bind_traits<Signature>::args_list;
  438. template <typename Signature>
  439. using function_signature_t = typename bind_traits<Signature>::signature_type;
  440. template <typename Signature>
  441. using function_return_t = typename bind_traits<Signature>::return_type;
  442. }} // namespace sol::meta
  443. #endif // SOL_BIND_TRAITS_HPP