import_mangled_helpers.hpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. // Copyright 2015-2018 Klemens D. Morgenstern
  2. //
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt
  5. // or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #ifndef BOOST_DLL_DETAIL_IMPORT_MANGLED_HELPERS_HPP_
  7. #define BOOST_DLL_DETAIL_IMPORT_MANGLED_HELPERS_HPP_
  8. #include <type_traits>
  9. #ifdef BOOST_HAS_PRAGMA_ONCE
  10. # pragma once
  11. #endif
  12. namespace boost { namespace dll { namespace experimental { namespace detail {
  13. //the following could be done by fusion, though it's simple enough to just declare it here.
  14. template<class ...Args>
  15. struct sequence {};
  16. template<class Value, class Seq> struct push_front;
  17. template<class Value, class ...Args>
  18. struct push_front<Value, sequence<Args...>>
  19. {
  20. typedef sequence<Value, Args...> type;
  21. };
  22. template<class Lhs, class Rhs>
  23. struct unqalified_is_same :
  24. std::is_same<
  25. typename std::remove_cv<Lhs>::type,
  26. typename std::remove_cv<Rhs>::type
  27. >
  28. {
  29. };
  30. /* ********************************** function sequence type traits ******************************/
  31. //determine if it's a sequence of functions.
  32. template<class T> struct is_function_seq;
  33. //type-trait for function overloads
  34. template<class Class, class...Args> struct is_function_seq<sequence<Class, Args...>>
  35. : std::conditional<
  36. std::is_function<Class>::value,
  37. is_function_seq<sequence<Args...>>,
  38. std::false_type>::type
  39. {};
  40. template<class Class>
  41. struct is_function_seq<sequence<Class>> : std::is_function<Class>
  42. {
  43. };
  44. template<>
  45. struct is_function_seq<sequence<>> : std::false_type
  46. {
  47. };
  48. /* ********************************* Function Tuple *************************** */
  49. //a tuple of plain functions.
  50. template <class ...Ts>
  51. struct function_tuple;
  52. template <class Return, class...Args, class T2, class ...Ts>
  53. struct function_tuple<Return(Args...), T2, Ts...>
  54. : function_tuple<T2, Ts...>
  55. {
  56. Return(*f_)(Args...);
  57. constexpr function_tuple(Return(* t)(Args...), T2* t2, Ts* ... ts)
  58. : function_tuple<T2, Ts...>(t2, ts...)
  59. , f_(t)
  60. {}
  61. Return operator()(Args...args) const {
  62. return (*f_)(static_cast<Args>(args)...);
  63. }
  64. using function_tuple<T2, Ts...>::operator();
  65. };
  66. template <class Return, class...Args>
  67. struct function_tuple<Return(Args...)> {
  68. Return(*f_)(Args...);
  69. constexpr function_tuple(Return(* t)(Args...))
  70. : f_(t)
  71. {}
  72. Return operator()(Args...args) const {
  73. return (*f_)(static_cast<Args>(args)...);
  74. }
  75. };
  76. /* ********************************** MemFn sequence type traits ******************************/
  77. template<class Class, class Func>
  78. struct mem_fn_def
  79. {
  80. typedef Class class_type;
  81. typedef Func func_type;
  82. typedef typename boost::dll::detail::get_mem_fn_type<Class, Func>::mem_fn mem_fn;
  83. };
  84. template<class ...Args>
  85. struct make_mem_fn_seq;
  86. // B: is T1 another version of T0?
  87. template<bool, class T0, class T1, class T2>
  88. struct make_mem_fn_seq_getter;
  89. template<class T0, class T1, class T2>
  90. struct make_mem_fn_seq_getter<true, T0, T1, T2>
  91. {
  92. typedef mem_fn_def<T1, T2> type;
  93. };
  94. template<class T0, class T1, class T2>
  95. struct make_mem_fn_seq_getter<false, T0, T1, T2>
  96. {
  97. typedef mem_fn_def<T0, T1> type;
  98. };
  99. template<class Class, class Signature>
  100. struct make_mem_fn_seq<Class, Signature>
  101. {
  102. typedef mem_fn_def<Class, Signature> mem_fn;
  103. typedef sequence<mem_fn> type;
  104. };
  105. template<class Class>
  106. struct make_mem_fn_seq<Class>
  107. {
  108. typedef sequence<> type;
  109. };
  110. template<class T0, class T1, class T2, class ... Args>
  111. struct make_mem_fn_seq<T0, T1, T2, Args...>
  112. {
  113. /* Since we might have ovls, it might be :
  114. * Class, void(int), void(int, int) //--> just us class for both
  115. * Class, const Class, void(int)//--> ovl class.
  116. *
  117. */
  118. static_assert(std::is_object<T0>::value, "");
  119. typedef typename make_mem_fn_seq_getter<
  120. unqalified_is_same<T0, T1>::value, T0, T1, T2>::type mem_fn_type;
  121. typedef typename std::conditional<
  122. unqalified_is_same<T0, T1>::value,
  123. make_mem_fn_seq<T1, Args...>,
  124. make_mem_fn_seq<T0, T2, Args...>> ::type next;
  125. typedef typename push_front<mem_fn_type, typename next::type>::type type;
  126. };
  127. /* Ok, this needs to be documented, so here's some pseudo-code:
  128. *
  129. * @code
  130. *
  131. * bool unqalified_is_same(lhs, rhs)
  132. * {
  133. * return remove_cv(lhs) == remove_cv(rhs);
  134. * }
  135. *
  136. * mem_fn make_mem_fn_seq_getter(b, cl, T2, T3)
  137. * {
  138. * if (b) //b means, that T2 is another version of cl, i.e. qualified
  139. * return get_mem_fn_type(T2, T3);
  140. * else //means that T2 is a function.
  141. * return get_mem_fn_type(cl, T2);
  142. * }
  143. *
  144. * sequence make_mem_fn_seq(type cl, type T2, type T3, types...)
  145. * {
  146. * mem_fn = make_mem_fn_seq_getter(
  147. * unqalified_is_same(cl, T2), cl, T2, T3);
  148. *
  149. * next = unqalified_is_same(cl, T2) ?
  150. * make_mem_fn_seq(T2, types...) //because: T2 is another version of cl, hence i use this. T3 was already consumed.
  151. * :
  152. * make_mem_fn_seq(Class, T3, types...) //because: T2 was a function, hence it is consumed and class remains unchanged.
  153. * ;
  154. * return push_front(mem_fn, next) ;
  155. * };
  156. * @endcode
  157. */
  158. template<class T, class U, class ...Args>
  159. struct is_mem_fn_seq_impl
  160. {
  161. typedef typename std::conditional<
  162. std::is_function<U>::value || boost::dll::experimental::detail::unqalified_is_same<T, U>::value,
  163. typename is_mem_fn_seq_impl<T, Args...>::type,
  164. std::false_type>::type type;
  165. };
  166. template<class T, class U>
  167. struct is_mem_fn_seq_impl<T, U>
  168. {
  169. typedef typename std::conditional<
  170. std::is_function<U>::value && std::is_object<T>::value,
  171. std::true_type, std::false_type>::type type;
  172. };
  173. template<class T, class U, class Last>
  174. struct is_mem_fn_seq_impl<T, U, Last>
  175. {
  176. typedef typename std::conditional<
  177. (std::is_function<U>::value || boost::dll::experimental::detail::unqalified_is_same<T, U>::value)
  178. && std::is_function<Last>::value,
  179. std::true_type, std::false_type>::type type;
  180. };
  181. template<class T> struct is_mem_fn_seq : std::false_type {};
  182. //If only two arguments are provided at all.
  183. template<class T, class U>
  184. struct is_mem_fn_seq<sequence<T, U>> : std::conditional<
  185. std::is_object<T>::value && std::is_function<U>::value,
  186. std::true_type, std::false_type>::type
  187. {
  188. };
  189. template<class T, class Func, class ...Args>
  190. struct is_mem_fn_seq<sequence<T, Func, Args...>> :
  191. std::conditional<
  192. std::is_class<T>::value && std::is_function<Func>::value,
  193. typename is_mem_fn_seq_impl<T, Args...>::type,
  194. std::false_type>::type {};
  195. /* ********************************** mem fn sequence tuple ******************************/
  196. /* A tuple of member functions
  197. * Unlike for plain functions a sequence here might contain classes as well as functions.
  198. */
  199. template <class ...Ts>
  200. struct mem_fn_tuple;
  201. template <class Class, class Return, class...Args, class T2, class ...Ts>
  202. struct mem_fn_tuple<mem_fn_def<Class, Return(Args...)>, T2, Ts...>
  203. : mem_fn_tuple<T2, Ts...>
  204. {
  205. typedef typename boost::dll::detail::get_mem_fn_type<Class, Return(Args...)>::mem_fn mem_fn;
  206. mem_fn f_;
  207. constexpr mem_fn_tuple(mem_fn f, typename T2::mem_fn t2, typename Ts::mem_fn ... ts)
  208. : mem_fn_tuple<T2, Ts...>(t2, ts...)
  209. , f_(f)
  210. {}
  211. Return operator()(Class* const cl, Args...args) const {
  212. return (cl->*f_)(static_cast<Args>(args)...);
  213. }
  214. using mem_fn_tuple<T2, Ts...>::operator();
  215. };
  216. template <class Class, class Return, class...Args>
  217. struct mem_fn_tuple<mem_fn_def<Class, Return(Args...)>> {
  218. typedef typename boost::dll::detail::get_mem_fn_type<Class, Return(Args...)>::mem_fn mem_fn;
  219. mem_fn f_;
  220. constexpr mem_fn_tuple(mem_fn f)
  221. : f_(f)
  222. {}
  223. Return operator()(Class * const cl, Args...args) const {
  224. return (cl->*f_)(static_cast<Args>(args)...);
  225. }
  226. };
  227. }}}}
  228. #endif /* BOOST_DLL_DETAIL_IMPORT_MANGLED_HELPERS_HPP_ */