is_invocable.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  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... 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<Callable, Args...>() == boost::callable_traits::is_invocable<Callable, Args...>()));
  26. #else
  27. CT_ASSERT((Expect == boost::callable_traits::is_invocable<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, foo>
  41. ,invoke_case<true, foo*>
  42. ,invoke_case<true, foo&>
  43. ,invoke_case<true, foo&&>
  44. ,invoke_case<true, std::reference_wrapper<foo>>
  45. ,invoke_case<false, foo const>
  46. ,invoke_case<false, foo const*>
  47. ,invoke_case<false, foo const&>
  48. ,invoke_case<false, foo const&&>
  49. ,invoke_case<false, std::reference_wrapper<foo const>>
  50. ,invoke_case<false, foo, int>
  51. ,invoke_case<false, foo*, int>
  52. ,invoke_case<false, foo&, int>
  53. ,invoke_case<false, foo&&, int>
  54. ,invoke_case<false, std::reference_wrapper<foo>, int>
  55. >();
  56. run_tests<void(foo::*)() LREF
  57. ,invoke_case<false, foo>
  58. ,invoke_case<true, foo*>
  59. ,invoke_case<true, foo&>
  60. ,invoke_case<false, foo&&>
  61. ,invoke_case<true, std::reference_wrapper<foo>>
  62. ,invoke_case<false, foo const>
  63. ,invoke_case<false, foo const*>
  64. ,invoke_case<false, foo const&>
  65. ,invoke_case<false, foo const&&>
  66. ,invoke_case<false, std::reference_wrapper<foo const>>
  67. ,invoke_case<false, foo, int>
  68. ,invoke_case<false, foo*, int>
  69. ,invoke_case<false, foo&, int>
  70. ,invoke_case<false, foo&&, int>
  71. ,invoke_case<false, std::reference_wrapper<foo>, int>
  72. >();
  73. run_tests<void(foo::*)() RREF
  74. ,invoke_case<true, foo>
  75. ,invoke_case<false, foo*>
  76. ,invoke_case<false, foo&>
  77. ,invoke_case<true, foo&&>
  78. ,invoke_case<false, std::reference_wrapper<foo>>
  79. ,invoke_case<false, foo const>
  80. ,invoke_case<false, foo const*>
  81. ,invoke_case<false, foo const&>
  82. ,invoke_case<false, foo const&&>
  83. ,invoke_case<false, std::reference_wrapper<foo const>>
  84. ,invoke_case<false, foo, int>
  85. ,invoke_case<false, foo*, int>
  86. ,invoke_case<false, foo&, int>
  87. ,invoke_case<false, foo&&, int>
  88. ,invoke_case<false, std::reference_wrapper<foo>, int>
  89. >();
  90. run_tests<void(foo::*)() const
  91. ,invoke_case<true, foo>
  92. ,invoke_case<true, foo*>
  93. ,invoke_case<true, foo&>
  94. ,invoke_case<true, foo&&>
  95. ,invoke_case<true, std::reference_wrapper<foo>>
  96. ,invoke_case<true, foo const>
  97. ,invoke_case<true, foo const*>
  98. ,invoke_case<true, foo const&>
  99. ,invoke_case<true, foo const&&>
  100. ,invoke_case<true, std::reference_wrapper<foo const>>
  101. ,invoke_case<false, foo, int>
  102. ,invoke_case<false, foo*, int>
  103. ,invoke_case<false, foo&, int>
  104. ,invoke_case<false, foo&&, int>
  105. ,invoke_case<false, std::reference_wrapper<foo>, int>
  106. >();
  107. // MSVC doesn't handle cv + ref qualifiers in expression sfinae correctly
  108. #ifndef BOOST_CLBL_TRTS_MSVC
  109. run_tests<void(foo::*)() const LREF
  110. ,invoke_case<false, foo>
  111. ,invoke_case<true, foo*>
  112. ,invoke_case<true, foo&>
  113. ,invoke_case<false, foo&&>
  114. ,invoke_case<true, std::reference_wrapper<foo>>
  115. ,invoke_case<false, foo const>
  116. ,invoke_case<true, foo const*>
  117. ,invoke_case<true, foo const&>
  118. ,invoke_case<false, foo const&&>
  119. ,invoke_case<true, std::reference_wrapper<foo const>>
  120. ,invoke_case<false, foo, int>
  121. ,invoke_case<false, foo*, int>
  122. ,invoke_case<false, foo&, int>
  123. ,invoke_case<false, foo&&, int>
  124. ,invoke_case<false, std::reference_wrapper<foo>, int>
  125. >();
  126. run_tests<void(foo::*)() const RREF
  127. ,invoke_case<true, foo>
  128. ,invoke_case<false, foo*>
  129. ,invoke_case<false, foo&>
  130. ,invoke_case<true, foo&&>
  131. ,invoke_case<false, std::reference_wrapper<foo>>
  132. ,invoke_case<true, foo const>
  133. ,invoke_case<false, foo const*>
  134. ,invoke_case<false, foo const&>
  135. ,invoke_case<true, foo const&&>
  136. ,invoke_case<false, std::reference_wrapper<foo const>>
  137. ,invoke_case<false, foo, int>
  138. ,invoke_case<false, foo*, int>
  139. ,invoke_case<false, foo&, int>
  140. ,invoke_case<false, foo&&, int>
  141. ,invoke_case<false, std::reference_wrapper<foo>, int>
  142. >();
  143. #endif // #ifndef BOOST_CLBL_TRTS_MSVC
  144. run_tests<int
  145. ,invoke_case<false, foo>
  146. ,invoke_case<false, foo*>
  147. ,invoke_case<false, foo&>
  148. ,invoke_case<false, foo&&>
  149. ,invoke_case<false, std::reference_wrapper<foo>>
  150. ,invoke_case<false, foo const>
  151. ,invoke_case<false, foo const*>
  152. ,invoke_case<false, foo const&>
  153. ,invoke_case<false, foo const&&>
  154. ,invoke_case<false, std::reference_wrapper<foo const>>
  155. ,invoke_case<false, foo, int>
  156. ,invoke_case<false, foo*, int>
  157. ,invoke_case<false, foo&, int>
  158. ,invoke_case<false, foo&&, int>
  159. ,invoke_case<false, std::reference_wrapper<foo>, int>
  160. >();
  161. auto f = [](int){};
  162. run_tests<decltype(f)
  163. ,invoke_case<true, int>
  164. ,invoke_case<true, char>
  165. ,invoke_case<false, void*>
  166. >();
  167. run_tests<decltype(f)&
  168. ,invoke_case<true, int>
  169. ,invoke_case<true, char>
  170. ,invoke_case<false, void*>
  171. >();
  172. run_tests<decltype(std::ref(f))
  173. ,invoke_case<true, int>
  174. ,invoke_case<true, char>
  175. ,invoke_case<false, void*>
  176. >();
  177. run_tests<decltype(std::ref(f))&
  178. ,invoke_case<true, int>
  179. ,invoke_case<true, char>
  180. ,invoke_case<false, void*>
  181. >();
  182. run_tests<decltype(std::ref(f))&&
  183. ,invoke_case<true, int>
  184. ,invoke_case<true, char>
  185. ,invoke_case<false, void*>
  186. >();
  187. run_tests<decltype(std::ref(f)) const &
  188. ,invoke_case<true, int>
  189. ,invoke_case<true, char>
  190. ,invoke_case<false, void*>
  191. >();
  192. run_tests<decltype(std::ref(f)) const &&
  193. ,invoke_case<true, int>
  194. ,invoke_case<true, char>
  195. ,invoke_case<false, void*>
  196. >();
  197. run_tests<decltype(f)&&
  198. ,invoke_case<true, int>
  199. ,invoke_case<true, char>
  200. ,invoke_case<false, void*>
  201. >();
  202. run_tests<decltype(f) const &
  203. ,invoke_case<true, int>
  204. ,invoke_case<true, char>
  205. ,invoke_case<false, void*>
  206. >();
  207. run_tests<decltype(f) const &&
  208. ,invoke_case<true, int>
  209. ,invoke_case<true, char>
  210. ,invoke_case<false, void*>
  211. >();
  212. auto g = [](){};
  213. run_tests<decltype(g)
  214. ,invoke_case<true>
  215. ,invoke_case<false, char>
  216. ,invoke_case<false, void*>
  217. >();
  218. run_tests<decltype(g)&
  219. ,invoke_case<true>
  220. ,invoke_case<false, char>
  221. ,invoke_case<false, void*>
  222. >();
  223. run_tests<decltype(std::ref(g))
  224. ,invoke_case<true>
  225. ,invoke_case<false, char>
  226. ,invoke_case<false, void*>
  227. >();
  228. run_tests<decltype(std::ref(g))&
  229. ,invoke_case<true>
  230. ,invoke_case<false, char>
  231. ,invoke_case<false, void*>
  232. >();
  233. run_tests<decltype(std::ref(g))&&
  234. ,invoke_case<true>
  235. ,invoke_case<false, char>
  236. ,invoke_case<false, void*>
  237. >();
  238. run_tests<decltype(std::ref(g)) const &
  239. ,invoke_case<true>
  240. ,invoke_case<false, char>
  241. ,invoke_case<false, void*>
  242. >();
  243. run_tests<decltype(std::ref(g)) const &&
  244. ,invoke_case<true>
  245. ,invoke_case<false, char>
  246. ,invoke_case<false, void*>
  247. >();
  248. run_tests<decltype(g)&&
  249. ,invoke_case<true>
  250. ,invoke_case<false, char>
  251. ,invoke_case<false, void*>
  252. >();
  253. run_tests<decltype(g) const &
  254. ,invoke_case<true>
  255. ,invoke_case<false, char>
  256. ,invoke_case<false, void*>
  257. >();
  258. run_tests<decltype(g) const &&
  259. ,invoke_case<true>
  260. ,invoke_case<false, char>
  261. ,invoke_case<false, void*>
  262. >();
  263. // libc++ requires constructible types be passed to std::is_invocable
  264. #ifndef _LIBCPP_VERSION
  265. run_tests<void(int)
  266. ,invoke_case<true, int>
  267. ,invoke_case<true, char>
  268. ,invoke_case<false, void*>
  269. >();
  270. run_tests<void(int) const
  271. ,invoke_case<false, int>
  272. ,invoke_case<false, char>
  273. ,invoke_case<false, void*>
  274. >();
  275. run_tests<void()
  276. ,invoke_case<false, int>
  277. ,invoke_case<false, char>
  278. ,invoke_case<false, void*>
  279. >();
  280. run_tests<void
  281. ,invoke_case<false, foo>
  282. ,invoke_case<false, foo*>
  283. ,invoke_case<false, foo&>
  284. ,invoke_case<false, foo&&>
  285. ,invoke_case<false, std::reference_wrapper<foo>>
  286. ,invoke_case<false, foo const>
  287. ,invoke_case<false, foo const*>
  288. ,invoke_case<false, foo const&>
  289. ,invoke_case<false, foo const&&>
  290. ,invoke_case<false, std::reference_wrapper<foo const>>
  291. ,invoke_case<false, foo, int>
  292. ,invoke_case<false, foo*, int>
  293. ,invoke_case<false, foo&, int>
  294. ,invoke_case<false, foo&&, int>
  295. ,invoke_case<false, std::reference_wrapper<foo>, int>
  296. >();
  297. #endif
  298. run_tests<int
  299. ,invoke_case<false, foo>
  300. ,invoke_case<false, foo*>
  301. ,invoke_case<false, foo&>
  302. ,invoke_case<false, foo&&>
  303. ,invoke_case<false, std::reference_wrapper<foo>>
  304. ,invoke_case<false, foo const>
  305. ,invoke_case<false, foo const*>
  306. ,invoke_case<false, foo const&>
  307. ,invoke_case<false, foo const&&>
  308. ,invoke_case<false, std::reference_wrapper<foo const>>
  309. ,invoke_case<false, foo, int>
  310. ,invoke_case<false, foo*, int>
  311. ,invoke_case<false, foo&, int>
  312. ,invoke_case<false, foo&&, int>
  313. ,invoke_case<false, std::reference_wrapper<foo>, int>
  314. >();
  315. run_tests<void*
  316. ,invoke_case<false, foo>
  317. ,invoke_case<false, foo*>
  318. ,invoke_case<false, foo&>
  319. ,invoke_case<false, foo&&>
  320. ,invoke_case<false, std::reference_wrapper<foo>>
  321. ,invoke_case<false, foo const>
  322. ,invoke_case<false, foo const*>
  323. ,invoke_case<false, foo const&>
  324. ,invoke_case<false, foo const&&>
  325. ,invoke_case<false, std::reference_wrapper<foo const>>
  326. ,invoke_case<false, foo, int>
  327. ,invoke_case<false, foo*, int>
  328. ,invoke_case<false, foo&, int>
  329. ,invoke_case<false, foo&&, int>
  330. ,invoke_case<false, std::reference_wrapper<foo>, int>
  331. >();
  332. }
  333. #endif //#ifdef BOOST_CLBL_TRTS_GCC_OLDER_THAN_4_9_2