traits_test.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. // Copyright 2021 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "dap/traits.h"
  15. #include "gmock/gmock.h"
  16. #include "gtest/gtest.h"
  17. namespace dap {
  18. namespace traits {
  19. namespace {
  20. struct S {};
  21. struct E : S {};
  22. void F1(S) {}
  23. void F3(int, S, float) {}
  24. void E1(E) {}
  25. void E3(int, E, float) {}
  26. } // namespace
  27. TEST(ParameterType, Function) {
  28. F1({}); // Avoid unused method warning
  29. F3(0, {}, 0); // Avoid unused method warning
  30. static_assert(std::is_same<ParameterType<decltype(&F1), 0>, S>::value, "");
  31. static_assert(std::is_same<ParameterType<decltype(&F3), 0>, int>::value, "");
  32. static_assert(std::is_same<ParameterType<decltype(&F3), 1>, S>::value, "");
  33. static_assert(std::is_same<ParameterType<decltype(&F3), 2>, float>::value,
  34. "");
  35. }
  36. TEST(ParameterType, Method) {
  37. class C {
  38. public:
  39. void F1(S) {}
  40. void F3(int, S, float) {}
  41. };
  42. C().F1({}); // Avoid unused method warning
  43. C().F3(0, {}, 0); // Avoid unused method warning
  44. static_assert(std::is_same<ParameterType<decltype(&C::F1), 0>, S>::value, "");
  45. static_assert(std::is_same<ParameterType<decltype(&C::F3), 0>, int>::value,
  46. "");
  47. static_assert(std::is_same<ParameterType<decltype(&C::F3), 1>, S>::value, "");
  48. static_assert(std::is_same<ParameterType<decltype(&C::F3), 2>, float>::value,
  49. "");
  50. }
  51. TEST(ParameterType, ConstMethod) {
  52. class C {
  53. public:
  54. void F1(S) const {}
  55. void F3(int, S, float) const {}
  56. };
  57. C().F1({}); // Avoid unused method warning
  58. C().F3(0, {}, 0); // Avoid unused method warning
  59. static_assert(std::is_same<ParameterType<decltype(&C::F1), 0>, S>::value, "");
  60. static_assert(std::is_same<ParameterType<decltype(&C::F3), 0>, int>::value,
  61. "");
  62. static_assert(std::is_same<ParameterType<decltype(&C::F3), 1>, S>::value, "");
  63. static_assert(std::is_same<ParameterType<decltype(&C::F3), 2>, float>::value,
  64. "");
  65. }
  66. TEST(ParameterType, StaticMethod) {
  67. class C {
  68. public:
  69. static void F1(S) {}
  70. static void F3(int, S, float) {}
  71. };
  72. C::F1({}); // Avoid unused method warning
  73. C::F3(0, {}, 0); // Avoid unused method warning
  74. static_assert(std::is_same<ParameterType<decltype(&C::F1), 0>, S>::value, "");
  75. static_assert(std::is_same<ParameterType<decltype(&C::F3), 0>, int>::value,
  76. "");
  77. static_assert(std::is_same<ParameterType<decltype(&C::F3), 1>, S>::value, "");
  78. static_assert(std::is_same<ParameterType<decltype(&C::F3), 2>, float>::value,
  79. "");
  80. }
  81. TEST(ParameterType, FunctionLike) {
  82. using F1 = std::function<void(S)>;
  83. using F3 = std::function<void(int, S, float)>;
  84. static_assert(std::is_same<ParameterType<F1, 0>, S>::value, "");
  85. static_assert(std::is_same<ParameterType<F3, 0>, int>::value, "");
  86. static_assert(std::is_same<ParameterType<F3, 1>, S>::value, "");
  87. static_assert(std::is_same<ParameterType<F3, 2>, float>::value, "");
  88. }
  89. TEST(ParameterType, Lambda) {
  90. auto l1 = [](S) {};
  91. auto l3 = [](int, S, float) {};
  92. static_assert(std::is_same<ParameterType<decltype(l1), 0>, S>::value, "");
  93. static_assert(std::is_same<ParameterType<decltype(l3), 0>, int>::value, "");
  94. static_assert(std::is_same<ParameterType<decltype(l3), 1>, S>::value, "");
  95. static_assert(std::is_same<ParameterType<decltype(l3), 2>, float>::value, "");
  96. }
  97. TEST(HasSignature, Function) {
  98. F1({}); // Avoid unused method warning
  99. F3(0, {}, 0); // Avoid unused method warning
  100. static_assert(HasSignature<decltype(&F1), decltype(&F1)>::value, "");
  101. static_assert(HasSignature<decltype(&F3), decltype(&F3)>::value, "");
  102. static_assert(HasSignature<decltype(&F3), decltype(&F3)>::value, "");
  103. static_assert(HasSignature<decltype(&F3), decltype(&F3)>::value, "");
  104. static_assert(!HasSignature<decltype(&F1), decltype(&F3)>::value, "");
  105. static_assert(!HasSignature<decltype(&F3), decltype(&F1)>::value, "");
  106. static_assert(!HasSignature<decltype(&F3), decltype(&F1)>::value, "");
  107. static_assert(!HasSignature<decltype(&F3), decltype(&F1)>::value, "");
  108. }
  109. TEST(HasSignature, Method) {
  110. class C {
  111. public:
  112. void F1(S) {}
  113. void F3(int, S, float) {}
  114. };
  115. C().F1({}); // Avoid unused method warning
  116. C().F3(0, {}, 0); // Avoid unused method warning
  117. static_assert(HasSignature<decltype(&C::F1), decltype(&F1)>::value, "");
  118. static_assert(HasSignature<decltype(&C::F3), decltype(&F3)>::value, "");
  119. static_assert(HasSignature<decltype(&C::F3), decltype(&F3)>::value, "");
  120. static_assert(HasSignature<decltype(&C::F3), decltype(&F3)>::value, "");
  121. static_assert(!HasSignature<decltype(&C::F1), decltype(&F3)>::value, "");
  122. static_assert(!HasSignature<decltype(&C::F3), decltype(&F1)>::value, "");
  123. static_assert(!HasSignature<decltype(&C::F3), decltype(&F1)>::value, "");
  124. static_assert(!HasSignature<decltype(&C::F3), decltype(&F1)>::value, "");
  125. }
  126. TEST(HasSignature, ConstMethod) {
  127. class C {
  128. public:
  129. void F1(S) const {}
  130. void F3(int, S, float) const {}
  131. };
  132. C().F1({}); // Avoid unused method warning
  133. C().F3(0, {}, 0); // Avoid unused method warning
  134. static_assert(HasSignature<decltype(&C::F1), decltype(&F1)>::value, "");
  135. static_assert(HasSignature<decltype(&C::F3), decltype(&F3)>::value, "");
  136. static_assert(HasSignature<decltype(&C::F3), decltype(&F3)>::value, "");
  137. static_assert(HasSignature<decltype(&C::F3), decltype(&F3)>::value, "");
  138. static_assert(!HasSignature<decltype(&C::F1), decltype(&F3)>::value, "");
  139. static_assert(!HasSignature<decltype(&C::F3), decltype(&F1)>::value, "");
  140. static_assert(!HasSignature<decltype(&C::F3), decltype(&F1)>::value, "");
  141. static_assert(!HasSignature<decltype(&C::F3), decltype(&F1)>::value, "");
  142. }
  143. TEST(HasSignature, StaticMethod) {
  144. class C {
  145. public:
  146. static void F1(S) {}
  147. static void F3(int, S, float) {}
  148. };
  149. C::F1({}); // Avoid unused method warning
  150. C::F3(0, {}, 0); // Avoid unused method warning
  151. static_assert(HasSignature<decltype(&C::F1), decltype(&F1)>::value, "");
  152. static_assert(HasSignature<decltype(&C::F3), decltype(&F3)>::value, "");
  153. static_assert(HasSignature<decltype(&C::F3), decltype(&F3)>::value, "");
  154. static_assert(HasSignature<decltype(&C::F3), decltype(&F3)>::value, "");
  155. static_assert(!HasSignature<decltype(&C::F1), decltype(&F3)>::value, "");
  156. static_assert(!HasSignature<decltype(&C::F3), decltype(&F1)>::value, "");
  157. static_assert(!HasSignature<decltype(&C::F3), decltype(&F1)>::value, "");
  158. static_assert(!HasSignature<decltype(&C::F3), decltype(&F1)>::value, "");
  159. }
  160. TEST(HasSignature, FunctionLike) {
  161. using f1 = std::function<void(S)>;
  162. using f3 = std::function<void(int, S, float)>;
  163. static_assert(HasSignature<f1, decltype(&F1)>::value, "");
  164. static_assert(HasSignature<f3, decltype(&F3)>::value, "");
  165. static_assert(HasSignature<f3, decltype(&F3)>::value, "");
  166. static_assert(HasSignature<f3, decltype(&F3)>::value, "");
  167. static_assert(!HasSignature<f1, decltype(&F3)>::value, "");
  168. static_assert(!HasSignature<f3, decltype(&F1)>::value, "");
  169. static_assert(!HasSignature<f3, decltype(&F1)>::value, "");
  170. static_assert(!HasSignature<f3, decltype(&F1)>::value, "");
  171. }
  172. TEST(HasSignature, Lambda) {
  173. auto l1 = [](S) {};
  174. auto l3 = [](int, S, float) {};
  175. static_assert(HasSignature<decltype(l1), decltype(&F1)>::value, "");
  176. static_assert(HasSignature<decltype(l3), decltype(&F3)>::value, "");
  177. static_assert(HasSignature<decltype(l3), decltype(&F3)>::value, "");
  178. static_assert(HasSignature<decltype(l3), decltype(&F3)>::value, "");
  179. static_assert(!HasSignature<decltype(l1), decltype(&F3)>::value, "");
  180. static_assert(!HasSignature<decltype(l3), decltype(&F1)>::value, "");
  181. static_assert(!HasSignature<decltype(l3), decltype(&F1)>::value, "");
  182. static_assert(!HasSignature<decltype(l3), decltype(&F1)>::value, "");
  183. }
  184. ////
  185. TEST(CompatibleWith, Function) {
  186. F1({}); // Avoid unused method warning
  187. F3(0, {}, 0); // Avoid unused method warning
  188. E1({}); // Avoid unused method warning
  189. E3(0, {}, 0); // Avoid unused method warning
  190. static_assert(CompatibleWith<decltype(&F1), decltype(&F1)>::value, "");
  191. static_assert(CompatibleWith<decltype(&F3), decltype(&F3)>::value, "");
  192. static_assert(CompatibleWith<decltype(&F3), decltype(&F3)>::value, "");
  193. static_assert(CompatibleWith<decltype(&F3), decltype(&F3)>::value, "");
  194. static_assert(!CompatibleWith<decltype(&F1), decltype(&F3)>::value, "");
  195. static_assert(!CompatibleWith<decltype(&F3), decltype(&F1)>::value, "");
  196. static_assert(!CompatibleWith<decltype(&F3), decltype(&F1)>::value, "");
  197. static_assert(!CompatibleWith<decltype(&F3), decltype(&F1)>::value, "");
  198. static_assert(CompatibleWith<decltype(&E1), decltype(&F1)>::value, "");
  199. static_assert(CompatibleWith<decltype(&E3), decltype(&F3)>::value, "");
  200. static_assert(CompatibleWith<decltype(&E3), decltype(&F3)>::value, "");
  201. static_assert(CompatibleWith<decltype(&E3), decltype(&F3)>::value, "");
  202. static_assert(!CompatibleWith<decltype(&F1), decltype(&E1)>::value, "");
  203. static_assert(!CompatibleWith<decltype(&F3), decltype(&E3)>::value, "");
  204. static_assert(!CompatibleWith<decltype(&F3), decltype(&E3)>::value, "");
  205. static_assert(!CompatibleWith<decltype(&F3), decltype(&E3)>::value, "");
  206. }
  207. TEST(CompatibleWith, Method) {
  208. class C {
  209. public:
  210. void F1(S) {}
  211. void F3(int, S, float) {}
  212. void E1(E) {}
  213. void E3(int, E, float) {}
  214. };
  215. C().F1({}); // Avoid unused method warning
  216. C().F3(0, {}, 0); // Avoid unused method warning
  217. C().E1({}); // Avoid unused method warning
  218. C().E3(0, {}, 0); // Avoid unused method warning
  219. static_assert(CompatibleWith<decltype(&C::F1), decltype(&F1)>::value, "");
  220. static_assert(CompatibleWith<decltype(&C::F3), decltype(&F3)>::value, "");
  221. static_assert(CompatibleWith<decltype(&C::F3), decltype(&F3)>::value, "");
  222. static_assert(CompatibleWith<decltype(&C::F3), decltype(&F3)>::value, "");
  223. static_assert(!CompatibleWith<decltype(&C::F1), decltype(&F3)>::value, "");
  224. static_assert(!CompatibleWith<decltype(&C::F3), decltype(&F1)>::value, "");
  225. static_assert(!CompatibleWith<decltype(&C::F3), decltype(&F1)>::value, "");
  226. static_assert(!CompatibleWith<decltype(&C::F3), decltype(&F1)>::value, "");
  227. static_assert(CompatibleWith<decltype(&C::E1), decltype(&C::F1)>::value, "");
  228. static_assert(CompatibleWith<decltype(&C::E3), decltype(&C::F3)>::value, "");
  229. static_assert(CompatibleWith<decltype(&C::E3), decltype(&C::F3)>::value, "");
  230. static_assert(CompatibleWith<decltype(&C::E3), decltype(&C::F3)>::value, "");
  231. static_assert(!CompatibleWith<decltype(&C::F1), decltype(&C::E1)>::value, "");
  232. static_assert(!CompatibleWith<decltype(&C::F3), decltype(&C::E3)>::value, "");
  233. static_assert(!CompatibleWith<decltype(&C::F3), decltype(&C::E3)>::value, "");
  234. static_assert(!CompatibleWith<decltype(&C::F3), decltype(&C::E3)>::value, "");
  235. }
  236. TEST(CompatibleWith, ConstMethod) {
  237. class C {
  238. public:
  239. void F1(S) const {}
  240. void F3(int, S, float) const {}
  241. void E1(E) const {}
  242. void E3(int, E, float) const {}
  243. };
  244. C().F1({}); // Avoid unused method warning
  245. C().F3(0, {}, 0); // Avoid unused method warning
  246. C().E1({}); // Avoid unused method warning
  247. C().E3(0, {}, 0); // Avoid unused method warning
  248. static_assert(CompatibleWith<decltype(&C::F1), decltype(&F1)>::value, "");
  249. static_assert(CompatibleWith<decltype(&C::F3), decltype(&F3)>::value, "");
  250. static_assert(CompatibleWith<decltype(&C::F3), decltype(&F3)>::value, "");
  251. static_assert(CompatibleWith<decltype(&C::F3), decltype(&F3)>::value, "");
  252. static_assert(!CompatibleWith<decltype(&C::F1), decltype(&F3)>::value, "");
  253. static_assert(!CompatibleWith<decltype(&C::F3), decltype(&F1)>::value, "");
  254. static_assert(!CompatibleWith<decltype(&C::F3), decltype(&F1)>::value, "");
  255. static_assert(!CompatibleWith<decltype(&C::F3), decltype(&F1)>::value, "");
  256. static_assert(CompatibleWith<decltype(&C::E1), decltype(&C::F1)>::value, "");
  257. static_assert(CompatibleWith<decltype(&C::E3), decltype(&C::F3)>::value, "");
  258. static_assert(CompatibleWith<decltype(&C::E3), decltype(&C::F3)>::value, "");
  259. static_assert(CompatibleWith<decltype(&C::E3), decltype(&C::F3)>::value, "");
  260. static_assert(!CompatibleWith<decltype(&C::F1), decltype(&C::E1)>::value, "");
  261. static_assert(!CompatibleWith<decltype(&C::F3), decltype(&C::E3)>::value, "");
  262. static_assert(!CompatibleWith<decltype(&C::F3), decltype(&C::E3)>::value, "");
  263. static_assert(!CompatibleWith<decltype(&C::F3), decltype(&C::E3)>::value, "");
  264. }
  265. TEST(CompatibleWith, StaticMethod) {
  266. class C {
  267. public:
  268. static void F1(S) {}
  269. static void F3(int, S, float) {}
  270. static void E1(E) {}
  271. static void E3(int, E, float) {}
  272. };
  273. C::F1({}); // Avoid unused method warning
  274. C::F3(0, {}, 0); // Avoid unused method warning
  275. C::E1({}); // Avoid unused method warning
  276. C::E3(0, {}, 0); // Avoid unused method warning
  277. static_assert(CompatibleWith<decltype(&C::F1), decltype(&F1)>::value, "");
  278. static_assert(CompatibleWith<decltype(&C::F3), decltype(&F3)>::value, "");
  279. static_assert(CompatibleWith<decltype(&C::F3), decltype(&F3)>::value, "");
  280. static_assert(CompatibleWith<decltype(&C::F3), decltype(&F3)>::value, "");
  281. static_assert(!CompatibleWith<decltype(&C::F1), decltype(&F3)>::value, "");
  282. static_assert(!CompatibleWith<decltype(&C::F3), decltype(&F1)>::value, "");
  283. static_assert(!CompatibleWith<decltype(&C::F3), decltype(&F1)>::value, "");
  284. static_assert(!CompatibleWith<decltype(&C::F3), decltype(&F1)>::value, "");
  285. static_assert(CompatibleWith<decltype(&C::E1), decltype(&C::F1)>::value, "");
  286. static_assert(CompatibleWith<decltype(&C::E3), decltype(&C::F3)>::value, "");
  287. static_assert(CompatibleWith<decltype(&C::E3), decltype(&C::F3)>::value, "");
  288. static_assert(CompatibleWith<decltype(&C::E3), decltype(&C::F3)>::value, "");
  289. static_assert(!CompatibleWith<decltype(&C::F1), decltype(&C::E1)>::value, "");
  290. static_assert(!CompatibleWith<decltype(&C::F3), decltype(&C::E3)>::value, "");
  291. static_assert(!CompatibleWith<decltype(&C::F3), decltype(&C::E3)>::value, "");
  292. static_assert(!CompatibleWith<decltype(&C::F3), decltype(&C::E3)>::value, "");
  293. }
  294. TEST(CompatibleWith, FunctionLike) {
  295. using f1 = std::function<void(S)>;
  296. using f3 = std::function<void(int, S, float)>;
  297. using e1 = std::function<void(E)>;
  298. using e3 = std::function<void(int, E, float)>;
  299. static_assert(CompatibleWith<f1, decltype(&F1)>::value, "");
  300. static_assert(CompatibleWith<f3, decltype(&F3)>::value, "");
  301. static_assert(CompatibleWith<f3, decltype(&F3)>::value, "");
  302. static_assert(CompatibleWith<f3, decltype(&F3)>::value, "");
  303. static_assert(!CompatibleWith<f1, decltype(&F3)>::value, "");
  304. static_assert(!CompatibleWith<f3, decltype(&F1)>::value, "");
  305. static_assert(!CompatibleWith<f3, decltype(&F1)>::value, "");
  306. static_assert(!CompatibleWith<f3, decltype(&F1)>::value, "");
  307. static_assert(CompatibleWith<e1, f1>::value, "");
  308. static_assert(CompatibleWith<e3, f3>::value, "");
  309. static_assert(CompatibleWith<e3, f3>::value, "");
  310. static_assert(CompatibleWith<e3, f3>::value, "");
  311. static_assert(!CompatibleWith<f1, e1>::value, "");
  312. static_assert(!CompatibleWith<f3, e3>::value, "");
  313. static_assert(!CompatibleWith<f3, e3>::value, "");
  314. static_assert(!CompatibleWith<f3, e3>::value, "");
  315. }
  316. TEST(CompatibleWith, Lambda) {
  317. auto f1 = [](S) {};
  318. auto f3 = [](int, S, float) {};
  319. auto e1 = [](E) {};
  320. auto e3 = [](int, E, float) {};
  321. static_assert(CompatibleWith<decltype(f1), decltype(&F1)>::value, "");
  322. static_assert(CompatibleWith<decltype(f3), decltype(&F3)>::value, "");
  323. static_assert(CompatibleWith<decltype(f3), decltype(&F3)>::value, "");
  324. static_assert(CompatibleWith<decltype(f3), decltype(&F3)>::value, "");
  325. static_assert(!CompatibleWith<decltype(f1), decltype(&F3)>::value, "");
  326. static_assert(!CompatibleWith<decltype(f3), decltype(&F1)>::value, "");
  327. static_assert(!CompatibleWith<decltype(f3), decltype(&F1)>::value, "");
  328. static_assert(!CompatibleWith<decltype(f3), decltype(&F1)>::value, "");
  329. static_assert(CompatibleWith<decltype(e1), decltype(f1)>::value, "");
  330. static_assert(CompatibleWith<decltype(e3), decltype(f3)>::value, "");
  331. static_assert(CompatibleWith<decltype(e3), decltype(f3)>::value, "");
  332. static_assert(CompatibleWith<decltype(e3), decltype(f3)>::value, "");
  333. static_assert(!CompatibleWith<decltype(f1), decltype(e1)>::value, "");
  334. static_assert(!CompatibleWith<decltype(f3), decltype(e3)>::value, "");
  335. static_assert(!CompatibleWith<decltype(f3), decltype(e3)>::value, "");
  336. static_assert(!CompatibleWith<decltype(f3), decltype(e3)>::value, "");
  337. }
  338. } // namespace traits
  339. } // namespace dap