handle_return.hpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. // This file is distributed under the BSD License.
  2. // See "license.txt" for details.
  3. // Copyright 2009-2012, Jonathan Turner ([email protected])
  4. // Copyright 2009-2017, Jason Turner ([email protected])
  5. // http://www.chaiscript.com
  6. // This is an open source non-commercial project. Dear PVS-Studio, please check it.
  7. // PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
  8. #ifndef CHAISCRIPT_HANDLE_RETURN_HPP_
  9. #define CHAISCRIPT_HANDLE_RETURN_HPP_
  10. #include <functional>
  11. #include <memory>
  12. #include <type_traits>
  13. #include "boxed_number.hpp"
  14. #include "boxed_value.hpp"
  15. namespace chaiscript {
  16. class Boxed_Number;
  17. } // namespace chaiscript
  18. namespace chaiscript
  19. {
  20. namespace dispatch
  21. {
  22. template<class T, class U> class Proxy_Function_Callable_Impl;
  23. template<class T> class Assignable_Proxy_Function_Impl;
  24. namespace detail
  25. {
  26. /// Used internally for handling a return value from a Proxy_Function call
  27. template<typename Ret>
  28. struct Handle_Return
  29. {
  30. template<typename T,
  31. typename = typename std::enable_if<std::is_pod<typename std::decay<T>::type>::value>::type>
  32. static Boxed_Value handle(T r)
  33. {
  34. return Boxed_Value(std::move(r), true);
  35. }
  36. template<typename T,
  37. typename = typename std::enable_if<!std::is_pod<typename std::decay<T>::type>::value>::type>
  38. static Boxed_Value handle(T &&r)
  39. {
  40. return Boxed_Value(std::make_shared<T>(std::forward<T>(r)), true);
  41. }
  42. };
  43. template<typename Ret>
  44. struct Handle_Return<const std::function<Ret> &>
  45. {
  46. static Boxed_Value handle(const std::function<Ret> &f) {
  47. return Boxed_Value(
  48. chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<Ret, std::function<Ret>>>(f)
  49. );
  50. }
  51. };
  52. template<typename Ret>
  53. struct Handle_Return<std::function<Ret>> : Handle_Return<const std::function<Ret> &>
  54. {
  55. };
  56. template<typename Ret>
  57. struct Handle_Return<const std::shared_ptr<std::function<Ret>>>
  58. {
  59. static Boxed_Value handle(const std::shared_ptr<std::function<Ret>> &f) {
  60. return Boxed_Value(
  61. chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Assignable_Proxy_Function_Impl<Ret>>(std::ref(*f),f)
  62. );
  63. }
  64. };
  65. template<typename Ret>
  66. struct Handle_Return<const std::shared_ptr<std::function<Ret>> &> : Handle_Return<const std::shared_ptr<std::function<Ret>>>
  67. {
  68. };
  69. template<typename Ret>
  70. struct Handle_Return<std::shared_ptr<std::function<Ret>>> : Handle_Return<const std::shared_ptr<std::function<Ret>>>
  71. {
  72. };
  73. template<typename Ret>
  74. struct Handle_Return<std::function<Ret> &>
  75. {
  76. static Boxed_Value handle(std::function<Ret> &f) {
  77. return Boxed_Value(
  78. chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Assignable_Proxy_Function_Impl<Ret>>(std::ref(f),
  79. std::shared_ptr<std::function<Ret>>())
  80. );
  81. }
  82. static Boxed_Value handle(const std::function<Ret> &f) {
  83. return Boxed_Value(
  84. chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<Ret, std::function<Ret>>>(f)
  85. );
  86. }
  87. };
  88. template<typename Ret>
  89. struct Handle_Return<Ret *&>
  90. {
  91. static Boxed_Value handle(Ret *p)
  92. {
  93. return Boxed_Value(p, true);
  94. }
  95. };
  96. template<typename Ret>
  97. struct Handle_Return<const Ret *&>
  98. {
  99. static Boxed_Value handle(const Ret *p)
  100. {
  101. return Boxed_Value(p, true);
  102. }
  103. };
  104. template<typename Ret>
  105. struct Handle_Return<Ret *>
  106. {
  107. static Boxed_Value handle(Ret *p)
  108. {
  109. return Boxed_Value(p, true);
  110. }
  111. };
  112. template<typename Ret>
  113. struct Handle_Return<const Ret *>
  114. {
  115. static Boxed_Value handle(const Ret *p)
  116. {
  117. return Boxed_Value(p, true);
  118. }
  119. };
  120. template<typename Ret>
  121. struct Handle_Return<std::shared_ptr<Ret> &>
  122. {
  123. static Boxed_Value handle(const std::shared_ptr<Ret> &r)
  124. {
  125. return Boxed_Value(r, true);
  126. }
  127. };
  128. template<typename Ret>
  129. struct Handle_Return<std::shared_ptr<Ret>> : Handle_Return<std::shared_ptr<Ret> &>
  130. {
  131. };
  132. template<typename Ret>
  133. struct Handle_Return<const std::shared_ptr<Ret> &> : Handle_Return<std::shared_ptr<Ret> &>
  134. {
  135. };
  136. template<typename Ret>
  137. struct Handle_Return<std::unique_ptr<Ret>> : Handle_Return<std::unique_ptr<Ret> &>
  138. {
  139. static Boxed_Value handle(std::unique_ptr<Ret> &&r)
  140. {
  141. return Boxed_Value(std::move(r), true);
  142. }
  143. };
  144. template<typename Ret>
  145. struct Handle_Return<const Ret &>
  146. {
  147. static Boxed_Value handle(const Ret &r)
  148. {
  149. return Boxed_Value(std::cref(r), true);
  150. }
  151. };
  152. template<typename Ret>
  153. struct Handle_Return<const Ret>
  154. {
  155. static Boxed_Value handle(Ret r)
  156. {
  157. return Boxed_Value(std::move(r));
  158. }
  159. };
  160. template<typename Ret>
  161. struct Handle_Return<Ret &>
  162. {
  163. static Boxed_Value handle(Ret &r)
  164. {
  165. return Boxed_Value(std::ref(r));
  166. }
  167. };
  168. template<>
  169. struct Handle_Return<Boxed_Value>
  170. {
  171. static Boxed_Value handle(const Boxed_Value &r)
  172. {
  173. return r;
  174. }
  175. };
  176. template<>
  177. struct Handle_Return<const Boxed_Value> : Handle_Return<Boxed_Value>
  178. {
  179. };
  180. template<>
  181. struct Handle_Return<Boxed_Value &> : Handle_Return<Boxed_Value>
  182. {
  183. };
  184. template<>
  185. struct Handle_Return<const Boxed_Value &> : Handle_Return<Boxed_Value>
  186. {
  187. };
  188. /**
  189. * Used internally for handling a return value from a Proxy_Function call
  190. */
  191. template<>
  192. struct Handle_Return<Boxed_Number>
  193. {
  194. static Boxed_Value handle(const Boxed_Number &r)
  195. {
  196. return r.bv;
  197. }
  198. };
  199. template<>
  200. struct Handle_Return<const Boxed_Number> : Handle_Return<Boxed_Number>
  201. {
  202. };
  203. /**
  204. * Used internally for handling a return value from a Proxy_Function call
  205. */
  206. template<>
  207. struct Handle_Return<void>
  208. {
  209. static Boxed_Value handle()
  210. {
  211. return void_var();
  212. }
  213. };
  214. }
  215. }
  216. }
  217. #endif