bind_internal.h 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. /**
  2. * Tencent is pleased to support the open source community by making Tars available.
  3. *
  4. * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
  5. *
  6. * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
  7. * in compliance with the License. You may obtain a copy of the License at
  8. *
  9. * https://opensource.org/licenses/BSD-3-Clause
  10. *
  11. * Unless required by applicable law or agreed to in writing, software distributed
  12. * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  13. * CONDITIONS OF ANY KIND, either express or implied. See the License for the
  14. * specific language governing permissions and limitations under the License.
  15. */
  16. #ifndef _TARS_BIND_INTERNAL_H_
  17. #define _TARS_BIND_INTERNAL_H_
  18. #include <memory>
  19. #include <tuple>
  20. #include <vector>
  21. #include "promise/function.h"
  22. namespace tars {
  23. namespace bind {
  24. template <size_t...>
  25. struct IndexSequence {};
  26. template <size_t... Ns>
  27. struct MakeIndexSequenceImpl;
  28. template <size_t... Ns>
  29. struct MakeIndexSequenceImpl<0, Ns...> {
  30. using Type = IndexSequence<Ns...>;
  31. };
  32. template <size_t N, size_t... Ns>
  33. struct MakeIndexSequenceImpl<N, Ns...>
  34. : MakeIndexSequenceImpl<N-1, N-1, Ns...> {};
  35. template <size_t N>
  36. using MakeIndexSequence = typename MakeIndexSequenceImpl<N>::Type;
  37. // Used to implement MakeArgsStorage.
  38. template <bool IsRefCall, typename... BoundArgs>
  39. struct MakeArgsStorageImpl {
  40. using Type = std::tuple<BoundArgs...>;
  41. };
  42. template <typename Obj, typename... BoundArgs>
  43. struct MakeArgsStorageImpl<true, Obj*, BoundArgs...> {
  44. using Type = std::tuple<std::shared_ptr<Obj>, BoundArgs...>;
  45. };
  46. template <bool IsRefCall, typename... BoundArgs>
  47. using MakeArgsStorage = typename MakeArgsStorageImpl<IsRefCall,
  48. typename std::decay<BoundArgs>::type...>::Type;
  49. class BindStateBase : public std::enable_shared_from_this<BindStateBase> {
  50. public:
  51. virtual ~BindStateBase() {};
  52. protected:
  53. BindStateBase() {}
  54. };
  55. template <typename Functor>
  56. class RunnableAdapter;
  57. template <typename R, typename... Args>
  58. class RunnableAdapter<R(*)(Args...)> {
  59. public:
  60. typedef R RunType(Args...);
  61. using IsMethod = std::false_type;
  62. explicit RunnableAdapter(R(*f)(Args...))
  63. : m_function(f)
  64. {
  65. }
  66. template <typename... RunArgs>
  67. R run(RunArgs&&... args)
  68. {
  69. return m_function(std::forward<RunArgs>(args)...);
  70. }
  71. private:
  72. R (*m_function)(Args...);
  73. };
  74. template <typename R, typename T, typename... Args>
  75. class RunnableAdapter<R(T::*)(Args...)> {
  76. public:
  77. typedef R RunType(T*, Args...);
  78. using IsMethod = std::true_type;
  79. explicit RunnableAdapter(R(T::*f)(Args...))
  80. : m_function(f)
  81. {
  82. }
  83. template <typename... RunArgs>
  84. R run(T* obj, RunArgs&&... args)
  85. {
  86. return (obj->*m_function)(std::forward<RunArgs>(args)...);
  87. }
  88. private:
  89. R (T::*m_function)(Args...);
  90. };
  91. template <typename R, typename T, typename... Args>
  92. class RunnableAdapter<R(T::*)(Args...) const> {
  93. public:
  94. typedef R RunType(const T*, Args...);
  95. using IsMethod = std::true_type;
  96. explicit RunnableAdapter(R(T::*f)(Args...) const)
  97. : m_function(f)
  98. {
  99. }
  100. template <typename... RunArgs>
  101. R run(const T* obj, RunArgs&&... args)
  102. {
  103. return (obj->*m_function)(std::forward<RunArgs>(args)...);
  104. }
  105. private:
  106. R (T::*m_function)(Args...) const;
  107. };
  108. template <typename T>
  109. struct FunctorTraits {
  110. using RunnableType = RunnableAdapter<T>;
  111. using RunType = typename RunnableType::RunType;
  112. };
  113. template <typename T>
  114. typename FunctorTraits<T>::RunnableType MakeRunnable(const T& t) {
  115. return RunnableAdapter<T>(t);
  116. }
  117. template <bool IsRefCall, typename R, typename Runnable>
  118. struct InvokeHelper;
  119. template <typename R, typename Runnable>
  120. struct InvokeHelper<false, R, Runnable> {
  121. template <typename... RunArgs>
  122. static R makeItSo(Runnable r, RunArgs&&... args)
  123. {
  124. return r.run(std::forward<RunArgs>(args)...);
  125. }
  126. };
  127. template <typename Runnable>
  128. struct InvokeHelper<false, void, Runnable> {
  129. template <typename... RunArgs>
  130. static void makeItSo(Runnable r, RunArgs&&... args)
  131. {
  132. r.run(std::forward<RunArgs>(args)...);
  133. }
  134. };
  135. template <typename R, typename Runnable>
  136. struct InvokeHelper<true, R, Runnable> {
  137. template <typename RefPtr, typename... RunArgs>
  138. static R makeItSo(Runnable r, RefPtr p, RunArgs&&... args)
  139. {
  140. return r.run(p.get(), std::forward<RunArgs>(args)...);
  141. }
  142. };
  143. template <typename Runnable>
  144. struct InvokeHelper<true, void, Runnable> {
  145. template <typename RefPtr, typename... RunArgs>
  146. static void makeItSo(Runnable r, RefPtr p, RunArgs&&... args)
  147. {
  148. r.run(p.get(), std::forward<RunArgs>(args)...);
  149. }
  150. };
  151. template <typename T>
  152. const T& Unwrap(const T& o) {
  153. return o;
  154. }
  155. template <typename T>
  156. struct IsMoveOnlyType : public std::false_type {};
  157. template <typename T, typename D>
  158. struct IsMoveOnlyType<std::unique_ptr<T, D> > : public std::true_type {};
  159. template <typename T, typename A>
  160. struct IsMoveOnlyType<std::vector<T, A> > : public IsMoveOnlyType<T> {};
  161. template <typename T>
  162. struct ParamForwardTypeNonMoveOnly {
  163. using ForwardType = const T&;
  164. };
  165. template <typename T, size_t N>
  166. struct ParamForwardTypeNonMoveOnly<T[N]> {
  167. using ForwardType = const T*;
  168. };
  169. template <typename T>
  170. struct ParamForwardTypeNonMoveOnly<T[]> {
  171. using ForwardType = const T*;
  172. };
  173. template <typename T>
  174. struct ParamForwardTypeMoveOnly {
  175. using ForwardType = T;
  176. };
  177. template <typename T>
  178. enable_if_t<!IsMoveOnlyType<T>::value, T>& ParamForward(T& t)
  179. {
  180. return t;
  181. }
  182. template <typename T>
  183. enable_if_t<IsMoveOnlyType<T>::value, T>& ParamForward(T& t)
  184. {
  185. return std::move(t);
  186. }
  187. template <typename T>
  188. struct ParamTraits : public std::conditional<IsMoveOnlyType<T>::value,
  189. ParamForwardTypeMoveOnly<T>,
  190. ParamForwardTypeNonMoveOnly<T> >::type {};
  191. template <typename BoundIndices, typename StorageType,
  192. typename InvokeHelperType, typename UnboundForwardRunType>
  193. struct Invoker;
  194. template <size_t... BoundIndices,
  195. typename StorageType,
  196. typename InvokeHelperType,
  197. typename R,
  198. typename... UnboundForwardArgs>
  199. struct Invoker<IndexSequence<BoundIndices...>, StorageType,
  200. InvokeHelperType, R(UnboundForwardArgs...)> {
  201. static R run(BindStateBase* base, UnboundForwardArgs... unbound_args)
  202. {
  203. StorageType* storage = static_cast<StorageType*>(base);
  204. return InvokeHelperType::makeItSo(storage->m_runnable,
  205. Unwrap(std::get<BoundIndices>(storage->m_boundArgs))...,
  206. ParamForward(unbound_args)...);
  207. }
  208. };
  209. template <bool IsMethod, typename... Args>
  210. struct IsRefMethod : public std::false_type {};
  211. template <typename T, typename... Args>
  212. struct IsRefMethod<true, std::shared_ptr<T>, Args...>
  213. : public std::true_type {};
  214. template <typename Runnable, typename RunType, typename... BoundArgs>
  215. struct BindState;
  216. template <typename Runnable,
  217. typename R,
  218. typename... Args,
  219. typename... BoundArgs>
  220. struct BindState<Runnable, R(Args...), BoundArgs...> final
  221. : public BindStateBase {
  222. private:
  223. using StorageType = BindState<Runnable, R(Args...), BoundArgs...>;
  224. using RunnableType = Runnable;
  225. using IsRefCall = IsRefMethod<Runnable::IsMethod::value,
  226. typename std::decay<BoundArgs>::type...>;
  227. using BoundIndices = MakeIndexSequence<sizeof...(BoundArgs)>;
  228. using UnboundForwardArgs = tl::DropTypeListItem<sizeof...(BoundArgs),
  229. tl::TypeList<typename ParamTraits<Args>::ForwardType...> >;
  230. using UnboundForwardRunType = f::MakeFunctionType<R, UnboundForwardArgs>;
  231. using InvokeHelperType = InvokeHelper<IsRefCall::value, R, Runnable>;
  232. using UnboundArgs = tl::DropTypeListItem<sizeof...(BoundArgs),
  233. tl::TypeList<Args...> >;
  234. public:
  235. using InvokerType = Invoker<BoundIndices,
  236. StorageType,
  237. InvokeHelperType,
  238. UnboundForwardRunType>;
  239. using UnboundRunType = f::MakeFunctionType<R, UnboundArgs>;
  240. template <typename... ForwardArgs>
  241. BindState(const Runnable& runnable, ForwardArgs&&... boundArgs)
  242. : m_runnable(runnable)
  243. , m_boundArgs(std::forward<ForwardArgs>(boundArgs)...)
  244. {
  245. }
  246. RunnableType m_runnable;
  247. MakeArgsStorage<IsRefCall::value, BoundArgs...> m_boundArgs;
  248. };
  249. } // end namespace bind
  250. } // end namespace tars
  251. #endif