is_invocable_r.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. /*
  2. Copyright Barrett Adair 2016-2017
  3. Distributed under the Boost Software License, Version 1.0.
  4. (See accompanying file LICENSE.md or copy at http ://boost.org/LICENSE_1_0.txt)
  5. */
  6. #include <type_traits>
  7. #include <functional>
  8. #include <utility>
  9. #include <boost/callable_traits/is_invocable.hpp>
  10. #include "test.hpp"
  11. #ifdef BOOST_CLBL_TRTS_GCC_OLDER_THAN_4_9_2
  12. //gcc < 4.9 doesn't like the invoke_case pattern used here
  13. int main(){}
  14. #else
  15. template<typename T>
  16. struct tag {
  17. using type = T;
  18. };
  19. template<bool Expect, typename Ret, typename... Args>
  20. struct invoke_case {
  21. template<typename Callable>
  22. void operator()(tag<Callable>) const {
  23. // when available, test parity with std implementation (c++2a breaks our expectations but we still match std impl)
  24. #if defined(__cpp_lib_is_invocable) || __cplusplus >= 201707L
  25. CT_ASSERT((std::is_invocable_r<Ret, Callable, Args...>() == boost::callable_traits::is_invocable_r<Ret, Callable, Args...>()));
  26. #else
  27. CT_ASSERT((Expect == boost::callable_traits::is_invocable_r<Ret, Callable, Args...>()));
  28. #endif
  29. }
  30. };
  31. template<typename Callable, typename... InvokeCases>
  32. void run_tests() {
  33. using ignored = int[];
  34. ignored x {(InvokeCases{}(tag<Callable>{}),0)..., 0};
  35. (void)x;
  36. }
  37. struct foo {};
  38. int main() {
  39. run_tests<void(foo::*)()
  40. ,invoke_case<true, void, foo>
  41. ,invoke_case<true, void, foo*>
  42. ,invoke_case<true, void, foo&>
  43. ,invoke_case<true, void, foo&&>
  44. ,invoke_case<true, void, std::reference_wrapper<foo>>
  45. ,invoke_case<false, int, foo>
  46. ,invoke_case<false, int, foo*>
  47. ,invoke_case<false, int, foo&>
  48. ,invoke_case<false, int, foo&&>
  49. ,invoke_case<false, int, std::reference_wrapper<foo>>
  50. ,invoke_case<false, void, foo const>
  51. ,invoke_case<false, void, foo const*>
  52. ,invoke_case<false, void, foo const&>
  53. ,invoke_case<false, void, foo const&&>
  54. ,invoke_case<false, void, std::reference_wrapper<foo const>>
  55. ,invoke_case<false, void, foo, int>
  56. ,invoke_case<false, void, foo*, int>
  57. ,invoke_case<false, void, foo&, int>
  58. ,invoke_case<false, void, foo&&, int>
  59. ,invoke_case<false, void, std::reference_wrapper<foo>, int>
  60. ,invoke_case<false, int, foo const>
  61. ,invoke_case<false, int, foo const*>
  62. ,invoke_case<false, int, foo const&>
  63. ,invoke_case<false, int, foo const&&>
  64. ,invoke_case<false, int, std::reference_wrapper<foo const>>
  65. ,invoke_case<false, int, foo, int>
  66. ,invoke_case<false, int, foo*, int>
  67. ,invoke_case<false, int, foo&, int>
  68. ,invoke_case<false, int, foo&&, int>
  69. ,invoke_case<false, int, std::reference_wrapper<foo>, int>
  70. >();
  71. run_tests<char(foo::*)()
  72. ,invoke_case<true, void, foo>
  73. ,invoke_case<true, void, foo*>
  74. ,invoke_case<true, void, foo&>
  75. ,invoke_case<true, void, foo&&>
  76. ,invoke_case<true, void, std::reference_wrapper<foo>>
  77. ,invoke_case<true, int, foo>
  78. ,invoke_case<true, int, foo*>
  79. ,invoke_case<true, int, foo&>
  80. ,invoke_case<true, int, foo&&>
  81. ,invoke_case<true, int, std::reference_wrapper<foo>>
  82. >();
  83. run_tests<void(foo::*)() LREF
  84. ,invoke_case<false, void, foo>
  85. ,invoke_case<true, void, foo*>
  86. ,invoke_case<true, void, foo&>
  87. ,invoke_case<false, int, foo*>
  88. ,invoke_case<false, int, foo&>
  89. ,invoke_case<false, void, foo&&>
  90. ,invoke_case<true, void, std::reference_wrapper<foo>>
  91. ,invoke_case<false, int, std::reference_wrapper<foo>>
  92. ,invoke_case<false, void, foo const>
  93. ,invoke_case<false, void, foo const*>
  94. ,invoke_case<false, void, foo const&>
  95. ,invoke_case<false, void, foo const&&>
  96. ,invoke_case<false, void, std::reference_wrapper<foo const>>
  97. ,invoke_case<false, void, foo, int>
  98. ,invoke_case<false, void, foo*, int>
  99. ,invoke_case<false, void, foo&, int>
  100. ,invoke_case<false, void, foo&&, int>
  101. ,invoke_case<false, void, std::reference_wrapper<foo>, int>
  102. >();
  103. run_tests<void(foo::*)() RREF
  104. ,invoke_case<true, void, foo>
  105. ,invoke_case<false, int, foo>
  106. ,invoke_case<false, void, foo*>
  107. ,invoke_case<false, void, foo&>
  108. ,invoke_case<true, void, foo&&>
  109. ,invoke_case<false, int, foo&&>
  110. ,invoke_case<false, void, std::reference_wrapper<foo>>
  111. ,invoke_case<false, void, foo const>
  112. ,invoke_case<false, void, foo const*>
  113. ,invoke_case<false, void, foo const&>
  114. ,invoke_case<false, void, foo const&&>
  115. ,invoke_case<false, void, std::reference_wrapper<foo const>>
  116. ,invoke_case<false, void, foo, int>
  117. ,invoke_case<false, void, foo*, int>
  118. ,invoke_case<false, void, foo&, int>
  119. ,invoke_case<false, void, foo&&, int>
  120. ,invoke_case<false, void, std::reference_wrapper<foo>, int>
  121. >();
  122. run_tests<void(foo::*)() const
  123. ,invoke_case<true, void, foo>
  124. ,invoke_case<true, void, foo*>
  125. ,invoke_case<true, void, foo&>
  126. ,invoke_case<true, void, foo&&>
  127. ,invoke_case<true, void, std::reference_wrapper<foo>>
  128. ,invoke_case<true, void, foo const>
  129. ,invoke_case<true, void, foo const*>
  130. ,invoke_case<true, void, foo const&>
  131. ,invoke_case<true, void, foo const&&>
  132. ,invoke_case<true, void, std::reference_wrapper<foo const>>
  133. ,invoke_case<false, int, foo>
  134. ,invoke_case<false, int, foo*>
  135. ,invoke_case<false, int, foo&>
  136. ,invoke_case<false, int, foo&&>
  137. ,invoke_case<false, int, std::reference_wrapper<foo>>
  138. ,invoke_case<false, int, foo const>
  139. ,invoke_case<false, int, foo const*>
  140. ,invoke_case<false, int, foo const&>
  141. ,invoke_case<false, int, foo const&&>
  142. ,invoke_case<false, int, std::reference_wrapper<foo const>>
  143. ,invoke_case<false, void, foo, int>
  144. ,invoke_case<false, void, foo*, int>
  145. ,invoke_case<false, void, foo&, int>
  146. ,invoke_case<false, void, foo&&, int>
  147. ,invoke_case<false, void, std::reference_wrapper<foo>, int>
  148. >();
  149. // MSVC doesn't handle cv + ref qualifiers in expression sfinae correctly
  150. #ifndef BOOST_CLBL_TRTS_MSVC
  151. run_tests<void(foo::*)() const LREF
  152. ,invoke_case<false, void, foo>
  153. ,invoke_case<true, void, foo*>
  154. ,invoke_case<true, void, foo&>
  155. ,invoke_case<false, int, foo*>
  156. ,invoke_case<false, int, foo&>
  157. ,invoke_case<false, void, foo&&>
  158. ,invoke_case<true, void, std::reference_wrapper<foo>>
  159. ,invoke_case<false, int, std::reference_wrapper<foo>>
  160. ,invoke_case<false, void, foo const>
  161. ,invoke_case<true, void, foo const*>
  162. ,invoke_case<true, void, foo const&>
  163. ,invoke_case<false, int, foo const*>
  164. ,invoke_case<false, int, foo const&>
  165. ,invoke_case<false, void, foo const&&>
  166. ,invoke_case<true, void, std::reference_wrapper<foo const>>
  167. ,invoke_case<false, int, std::reference_wrapper<foo const>>
  168. ,invoke_case<false, void, foo, int>
  169. ,invoke_case<false, void, foo*, int>
  170. ,invoke_case<false, void, foo&, int>
  171. ,invoke_case<false, void, foo&&, int>
  172. ,invoke_case<false, void, std::reference_wrapper<foo>, int>
  173. >();
  174. run_tests<void(foo::*)() const RREF
  175. ,invoke_case<true, void, foo>
  176. ,invoke_case<false, int, foo>
  177. ,invoke_case<false, void, foo*>
  178. ,invoke_case<false, void, foo&>
  179. ,invoke_case<true, void, foo&&>
  180. ,invoke_case<false, int, foo&&>
  181. ,invoke_case<false, void, std::reference_wrapper<foo>>
  182. ,invoke_case<true, void, foo const>
  183. ,invoke_case<false, int, foo const>
  184. ,invoke_case<false, void, foo const*>
  185. ,invoke_case<false, void, foo const&>
  186. ,invoke_case<true, void, foo const&&>
  187. ,invoke_case<false, int, foo const&&>
  188. ,invoke_case<false, void, std::reference_wrapper<foo const>>
  189. ,invoke_case<false, void, foo, int>
  190. ,invoke_case<false, void, foo*, int>
  191. ,invoke_case<false, void, foo&, int>
  192. ,invoke_case<false, void, foo&&, int>
  193. ,invoke_case<false, void, std::reference_wrapper<foo>, int>
  194. >();
  195. #endif // #ifndef BOOST_CLBL_TRTS_MSVC
  196. run_tests<int
  197. ,invoke_case<false, void, foo>
  198. ,invoke_case<false, void, foo*>
  199. ,invoke_case<false, void, foo&>
  200. ,invoke_case<false, void, foo&&>
  201. ,invoke_case<false, void, std::reference_wrapper<foo>>
  202. ,invoke_case<false, void, foo const>
  203. ,invoke_case<false, void, foo const*>
  204. ,invoke_case<false, void, foo const&>
  205. ,invoke_case<false, void, foo const&&>
  206. ,invoke_case<false, void, std::reference_wrapper<foo const>>
  207. ,invoke_case<false, void, foo, int>
  208. ,invoke_case<false, void, foo*, int>
  209. ,invoke_case<false, void, foo&, int>
  210. ,invoke_case<false, void, foo&&, int>
  211. ,invoke_case<false, void, std::reference_wrapper<foo>, int>
  212. >();
  213. auto f = [](int){};
  214. run_tests<decltype(f)
  215. ,invoke_case<true, void, int>
  216. ,invoke_case<true, void, char>
  217. ,invoke_case<false, int, int>
  218. ,invoke_case<false, int, char>
  219. ,invoke_case<false, void, void*>
  220. >();
  221. auto g = [](){};
  222. run_tests<decltype(g)
  223. ,invoke_case<true, void>
  224. ,invoke_case<true, void>
  225. ,invoke_case<false, void, int>
  226. ,invoke_case<false, void, char>
  227. ,invoke_case<false, int, int>
  228. ,invoke_case<false, int, char>
  229. ,invoke_case<false, void, void*>
  230. >();
  231. // libc++ requires constructible types be passed to std::is_invocable
  232. #ifndef _LIBCPP_VERSION
  233. run_tests<void(int)
  234. ,invoke_case<true, void, int>
  235. ,invoke_case<true, void, char>
  236. ,invoke_case<false, int, int>
  237. ,invoke_case<false, int, char>
  238. ,invoke_case<false, void, void*>
  239. >();
  240. run_tests<void()
  241. ,invoke_case<false, void, int>
  242. ,invoke_case<false, void, char>
  243. ,invoke_case<false, void, void*>
  244. >();
  245. run_tests<void
  246. ,invoke_case<false, void, foo>
  247. ,invoke_case<false, void, foo*>
  248. ,invoke_case<false, void, foo&>
  249. ,invoke_case<false, void, foo&&>
  250. ,invoke_case<false, void, std::reference_wrapper<foo>>
  251. ,invoke_case<false, void, foo const>
  252. ,invoke_case<false, void, foo const*>
  253. ,invoke_case<false, void, foo const&>
  254. ,invoke_case<false, void, foo const&&>
  255. ,invoke_case<false, void, std::reference_wrapper<foo const>>
  256. ,invoke_case<false, void, foo, int>
  257. ,invoke_case<false, void, foo*, int>
  258. ,invoke_case<false, void, foo&, int>
  259. ,invoke_case<false, void, foo&&, int>
  260. ,invoke_case<false, void, std::reference_wrapper<foo>, int>
  261. >();
  262. #endif
  263. run_tests<int
  264. ,invoke_case<false, void, foo>
  265. ,invoke_case<false, void, foo*>
  266. ,invoke_case<false, void, foo&>
  267. ,invoke_case<false, void, foo&&>
  268. ,invoke_case<false, void, std::reference_wrapper<foo>>
  269. ,invoke_case<false, void, foo const>
  270. ,invoke_case<false, void, foo const*>
  271. ,invoke_case<false, void, foo const&>
  272. ,invoke_case<false, void, foo const&&>
  273. ,invoke_case<false, void, std::reference_wrapper<foo const>>
  274. ,invoke_case<false, void, foo, int>
  275. ,invoke_case<false, void, foo*, int>
  276. ,invoke_case<false, void, foo&, int>
  277. ,invoke_case<false, void, foo&&, int>
  278. ,invoke_case<false, void, std::reference_wrapper<foo>, int>
  279. >();
  280. run_tests<void*
  281. ,invoke_case<false, void, foo>
  282. ,invoke_case<false, void, foo*>
  283. ,invoke_case<false, void, foo&>
  284. ,invoke_case<false, void, foo&&>
  285. ,invoke_case<false, void, std::reference_wrapper<foo>>
  286. ,invoke_case<false, void, foo const>
  287. ,invoke_case<false, void, foo const*>
  288. ,invoke_case<false, void, foo const&>
  289. ,invoke_case<false, void, foo const&&>
  290. ,invoke_case<false, void, std::reference_wrapper<foo const>>
  291. ,invoke_case<false, void, foo, int>
  292. ,invoke_case<false, void, foo*, int>
  293. ,invoke_case<false, void, foo&, int>
  294. ,invoke_case<false, void, foo&&, int>
  295. ,invoke_case<false, void, std::reference_wrapper<foo>, int>
  296. >();
  297. }
  298. #endif //#ifdef BOOST_CLBL_TRTS_GCC_OLDER_THAN_4_9_2