Micro template library A library for building device drivers
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 

423 lignes
17 KiB

  1. /*!
  2. * \file Tmeta.cpp
  3. *
  4. * Copyright (C) 2018 Christos Choutouridis
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Lesser General Public License as
  8. * published by the Free Software Foundation, either version 3
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. *
  19. */
  20. #include <utl/concepts/concepts.h>
  21. #include <utl/meta/meta.h>
  22. #include <gtest/gtest.h>
  23. namespace test_concepts {
  24. using namespace utl;
  25. /*
  26. * Fixture like types
  27. */
  28. struct Empty { };
  29. struct HaveOnlyCopy {
  30. HaveOnlyCopy(const HaveOnlyCopy&) = default;
  31. HaveOnlyCopy(HaveOnlyCopy&&) = delete;
  32. HaveOnlyCopy& operator= (const HaveOnlyCopy&) = default;
  33. HaveOnlyCopy& operator= (HaveOnlyCopy&&) = delete;
  34. };
  35. struct HaveOnlyMove {
  36. HaveOnlyMove(const HaveOnlyMove&) = delete;
  37. HaveOnlyMove(HaveOnlyMove&&) = default;
  38. HaveOnlyMove& operator= (const HaveOnlyMove&) = delete;
  39. HaveOnlyMove& operator= (HaveOnlyMove&&) = default;
  40. };
  41. struct HaveCopyAndMove {
  42. HaveCopyAndMove(const HaveCopyAndMove&) = default;
  43. HaveCopyAndMove(HaveCopyAndMove&&) = default;
  44. HaveCopyAndMove& operator= (const HaveCopyAndMove&) = default;
  45. HaveCopyAndMove& operator= (HaveCopyAndMove&&) = default;
  46. };
  47. class HavePerfectForwarding {
  48. public: template<class T> HavePerfectForwarding(T&&) { }
  49. };
  50. class Base { };
  51. class Derived1 : public Base { };
  52. class Derived2 : public Derived1 { };
  53. class HaveOperatorBase {
  54. public: operator Base() { return base; }
  55. Base base;
  56. };
  57. struct A {
  58. int a_;
  59. public:
  60. A(int a =0) : a_{a} { };
  61. A(const A&) = default;
  62. A(A&&) = default;
  63. };
  64. bool operator== (const A& l, const A& r) { return l.a_ == r.a_; }
  65. bool operator!= (const A& l, const A& r) { return l.a_ != r.a_; }
  66. struct B {
  67. int b_;
  68. public:
  69. B(int b =0) : b_{b} { };
  70. B(const B&) = default;
  71. B(B&&) = default;
  72. B& operator= (const B&) = default;
  73. B& operator= (B&&) = default;
  74. };
  75. bool operator== (const B& l, const B& r) { return l.b_ == r.b_; }
  76. bool operator!= (const B& l, const B& r) { return l.b_ != r.b_; }
  77. bool operator< (const B& l, const B& r) { return l.b_ < r.b_; }
  78. bool operator<= (const B& l, const B& r) { return l.b_ <= r.b_; }
  79. bool operator> (const B& l, const B& r) { return l.b_ > r.b_; }
  80. bool operator>= (const B& l, const B& r) { return l.b_ >= r.b_; }
  81. TEST(TConcepts, Same) {
  82. // Same
  83. EXPECT_EQ (true, (Same<int, int>));
  84. EXPECT_EQ (false, (Same<int, long>));
  85. EXPECT_EQ (true, (Same<int*, int*>));
  86. EXPECT_EQ (true, (Same<double&, double&>));
  87. EXPECT_EQ (false, (Same<int, Empty>));
  88. EXPECT_EQ (false, (Same<Base, Derived1>));
  89. }
  90. TEST(TConcepts, DerivedFrom) {
  91. // DerivedFrom
  92. EXPECT_EQ (true, (DerivedFrom<Derived1, Base>));
  93. EXPECT_EQ (true, (DerivedFrom<Derived2, Derived1>));
  94. EXPECT_EQ (true, (DerivedFrom<Derived2, Base>));
  95. EXPECT_EQ (false, (DerivedFrom<Base, Derived1>));
  96. EXPECT_EQ (false, (DerivedFrom<Base, int>));
  97. EXPECT_EQ (false, (DerivedFrom<void, int>));
  98. }
  99. TEST(TConcepts, ConvertibleTo) {
  100. // ConvertibleTo
  101. EXPECT_EQ (true, (ConvertibleTo<void, void>));
  102. EXPECT_EQ (false, (ConvertibleTo<Base, void>));
  103. EXPECT_EQ (false, (ConvertibleTo<Base*, Derived1*>));
  104. EXPECT_EQ (true, (ConvertibleTo<Derived1*, Base*>));
  105. EXPECT_EQ (true, (ConvertibleTo<HaveOperatorBase, Base>));
  106. EXPECT_EQ (true, (ConvertibleTo<Base, HavePerfectForwarding>));
  107. }
  108. TEST(TConcepts, CommonReference) {
  109. // CommonReference
  110. EXPECT_EQ (true, (CommonReference<Derived1, Base>));
  111. EXPECT_EQ (true, (CommonReference<Derived1&, Base>));
  112. EXPECT_EQ (true, (CommonReference<const Empty&&, const Empty&>));
  113. EXPECT_EQ (false, (CommonReference<Empty&, const volatile Empty&>));
  114. //FIXME: CommonReference needs SFINAE friendly implementation
  115. //EXPECT_EQ (false, (CommonReference<Empty&&, const volatile Empty&>)); <- yields compiler error
  116. // Common
  117. EXPECT_EQ (true, (Common<int, int>));
  118. EXPECT_EQ (true, (Common<Base, Derived1>));
  119. EXPECT_EQ (true, (Common<Derived1, Derived2>));
  120. EXPECT_EQ (true, (Common<Base, HaveOperatorBase>));
  121. EXPECT_EQ (true, (Common<Base, HavePerfectForwarding>));
  122. }
  123. TEST(TConcepts, Integral) {
  124. // Integral
  125. EXPECT_EQ (false, (Integral<void>));
  126. EXPECT_EQ (true, (Integral<int>));
  127. EXPECT_EQ (true, (Integral<bool>));
  128. EXPECT_EQ (false, (Integral<int*>));
  129. EXPECT_EQ (false, (Integral<Base>));
  130. EXPECT_EQ (true, (Integral<meta::int_<42>::value_type>));
  131. EXPECT_EQ (false, (Integral<meta::int_<42>::type>));
  132. // SignedIntegral
  133. EXPECT_EQ (false, (SignedIntegral<void>));
  134. EXPECT_EQ (true, (SignedIntegral<int>));
  135. EXPECT_EQ (false, (SignedIntegral<int*>));
  136. EXPECT_EQ (false, (SignedIntegral<unsigned long>));
  137. EXPECT_EQ (false, (SignedIntegral<double>));
  138. EXPECT_EQ (false, (SignedIntegral<Base>));
  139. EXPECT_EQ (true, (SignedIntegral<meta::int16_<42>::value_type>));
  140. // UnsignedIntegral
  141. EXPECT_EQ (false, (UnsignedIntegral<void>));
  142. EXPECT_EQ (true, (UnsignedIntegral<unsigned int>));
  143. EXPECT_EQ (false, (UnsignedIntegral<long>));
  144. EXPECT_EQ (false, (UnsignedIntegral<double>));
  145. EXPECT_EQ (false, (UnsignedIntegral<Base>));
  146. EXPECT_EQ (true, (UnsignedIntegral<meta::uint16_<42>::value_type>));
  147. }
  148. TEST(TConcepts, Assignable) {
  149. // MoveAssignable
  150. EXPECT_EQ (false, (MoveAssignable<void>));
  151. EXPECT_EQ (true, (MoveAssignable<void*>));
  152. EXPECT_EQ (true, (MoveAssignable<int>));
  153. EXPECT_EQ (true, (MoveAssignable<int*>));
  154. EXPECT_EQ (false, (MoveAssignable<HaveOnlyCopy>));
  155. EXPECT_EQ (true, (MoveAssignable<HaveOnlyMove>));
  156. EXPECT_EQ (true, (MoveAssignable<HaveCopyAndMove>));
  157. EXPECT_EQ (true, (MoveAssignable<Empty>));
  158. EXPECT_EQ (true, (MoveAssignable<HavePerfectForwarding>));
  159. // CopyAssignable
  160. EXPECT_EQ (false, (CopyAssignable<void>));
  161. EXPECT_EQ (true, (CopyAssignable<void*>));
  162. EXPECT_EQ (true, (CopyAssignable<int>));
  163. EXPECT_EQ (true, (CopyAssignable<int*>));
  164. EXPECT_EQ (true, (CopyAssignable<HaveOnlyCopy>));
  165. EXPECT_EQ (false, (CopyAssignable<HaveOnlyMove>));
  166. EXPECT_EQ (true, (CopyAssignable<HaveCopyAndMove>));
  167. EXPECT_EQ (true, (CopyAssignable<Empty>));
  168. EXPECT_EQ (true, (CopyAssignable<HavePerfectForwarding>));
  169. // Assignable
  170. EXPECT_EQ (false, (Assignable<void, void>));
  171. EXPECT_EQ (false, (Assignable<int&, void>));
  172. EXPECT_EQ (true, (Assignable<int&, int>));
  173. EXPECT_EQ (false, (Assignable<int, int>));
  174. EXPECT_EQ (false, (Assignable<int*, int*>));
  175. EXPECT_EQ (true, (Assignable<Base&, Derived1>));
  176. EXPECT_EQ (false, (Assignable<Derived1&, Base>));
  177. EXPECT_EQ (true, (Assignable<HaveOnlyMove&, HaveOnlyMove&&>));
  178. EXPECT_EQ (true , (Assignable<HaveOnlyMove&, HaveOnlyMove>));
  179. EXPECT_EQ (true, (Assignable<Empty&, Empty>));
  180. }
  181. TEST(TConcepts, Swappable) {
  182. // Swappable, SwappableWith
  183. EXPECT_EQ (false, (Swappable<void>));
  184. EXPECT_EQ (true, (Swappable<void*>));
  185. EXPECT_EQ (true, (Swappable<int>));
  186. EXPECT_EQ (true, (Swappable<Base>));
  187. EXPECT_EQ (true, (SwappableWith<int, int>));
  188. EXPECT_EQ (false, (SwappableWith<int, Base>));
  189. EXPECT_EQ (false, (SwappableWith<Base, Derived1>));
  190. // Destructible
  191. EXPECT_EQ (false, (Destructible<void>));
  192. EXPECT_EQ (true, (Destructible<void*>));
  193. EXPECT_EQ (true, (Destructible<int>));
  194. EXPECT_EQ (true, (Destructible<int&>));
  195. EXPECT_EQ (true, (Destructible<Base>));
  196. EXPECT_EQ (true, (Destructible<HavePerfectForwarding>));
  197. }
  198. TEST(TConcepts, Constructible) {
  199. // Constructible
  200. EXPECT_EQ (false, (Constructible<void>));
  201. EXPECT_EQ (true, (Constructible<void*>));
  202. EXPECT_EQ (true, (Constructible<Base>));
  203. EXPECT_EQ (false, (Constructible<HaveOnlyMove>));
  204. EXPECT_EQ (true, (Constructible<HavePerfectForwarding, int>));
  205. // DefaultConstructible
  206. EXPECT_EQ (false, (DefaultConstructible<void>));
  207. EXPECT_EQ (true, (DefaultConstructible<void*>));
  208. EXPECT_EQ (false, (DefaultConstructible<int&>));
  209. EXPECT_EQ (true, (DefaultConstructible<Base>));
  210. EXPECT_EQ (true, (DefaultConstructible<Derived1>));
  211. EXPECT_EQ (false, (DefaultConstructible<HaveOnlyCopy>));
  212. EXPECT_EQ (false, (DefaultConstructible<HaveOnlyMove>));
  213. EXPECT_EQ (false, (DefaultConstructible<HavePerfectForwarding>));
  214. // MoveConstructible
  215. EXPECT_EQ (false, (MoveConstructible<void>));
  216. EXPECT_EQ (true, (MoveConstructible<void*>));
  217. EXPECT_EQ (true, (MoveConstructible<Base>));
  218. EXPECT_EQ (true, (MoveConstructible<Derived1>));
  219. EXPECT_EQ (true, (MoveConstructible<HaveOnlyMove>));
  220. EXPECT_EQ (false, (MoveConstructible<HaveOnlyCopy>));
  221. EXPECT_EQ (true, (MoveConstructible<HaveCopyAndMove>));
  222. EXPECT_EQ (true , (MoveConstructible<HavePerfectForwarding>));
  223. // CopyConstructible
  224. EXPECT_EQ (false, (CopyConstructible<void>));
  225. EXPECT_EQ (true, (CopyConstructible<void*>));
  226. EXPECT_EQ (true, (CopyConstructible<Base>));
  227. EXPECT_EQ (true, (CopyConstructible<Derived1>));
  228. EXPECT_EQ (false, (CopyConstructible<HaveOnlyMove>));
  229. EXPECT_EQ (false, (CopyConstructible<HaveOnlyCopy>));
  230. EXPECT_EQ (true, (CopyConstructible<HaveCopyAndMove>));
  231. EXPECT_EQ (true , (CopyConstructible<HavePerfectForwarding>));
  232. }
  233. TEST(TConcepts, MovableCopyable) {
  234. // Movable
  235. EXPECT_EQ (false, (Movable<void>));
  236. EXPECT_EQ (true, (Movable<int>));
  237. EXPECT_EQ (true, (Movable<Base>));
  238. EXPECT_EQ (true, (Movable<Derived1>));
  239. EXPECT_EQ (true, (Movable<HaveOnlyMove>));
  240. EXPECT_EQ (false, (Movable<HaveOnlyCopy>));
  241. EXPECT_EQ (true, (Movable<HaveCopyAndMove>));
  242. EXPECT_EQ (true , (Movable<HavePerfectForwarding>));
  243. // Copyable
  244. EXPECT_EQ (false, (Copyable<void>));
  245. EXPECT_EQ (true, (Copyable<int>));
  246. EXPECT_EQ (true, (Copyable<Base>));
  247. EXPECT_EQ (true, (Copyable<Derived1>));
  248. EXPECT_EQ (false, (Copyable<HaveOnlyMove>));
  249. EXPECT_EQ (false, (Copyable<HaveOnlyCopy>));
  250. EXPECT_EQ (true, (Copyable<HaveCopyAndMove>));
  251. EXPECT_EQ (true , (Copyable<HavePerfectForwarding>));
  252. }
  253. TEST(TConcepts, Boolean) {
  254. // Boolean
  255. EXPECT_EQ (false, (Boolean<void>));
  256. EXPECT_EQ (true, (Boolean<bool>));
  257. EXPECT_EQ (true, (Boolean<int>));
  258. EXPECT_EQ (true, (Boolean<double>));
  259. EXPECT_EQ (true, (Boolean<std::true_type>));
  260. EXPECT_EQ (true, (Boolean<meta::true_>));
  261. EXPECT_EQ (false, (Boolean<Empty>));
  262. }
  263. TEST(TConcepts, Comparable) {
  264. // EqualityComparable
  265. EXPECT_EQ (false, (EqualityComparable<void>));
  266. EXPECT_EQ (true, (EqualityComparable<bool>));
  267. EXPECT_EQ (true, (EqualityComparable<int>));
  268. EXPECT_EQ (false, (EqualityComparable<Empty>));
  269. EXPECT_EQ (true, (EqualityComparable<A>));
  270. // EqualityComparableWith
  271. EXPECT_EQ (false, (EqualityComparableWith<void, bool>));
  272. EXPECT_EQ (false, (EqualityComparableWith<void, void>));
  273. EXPECT_EQ (true, (EqualityComparableWith<bool, bool>));
  274. EXPECT_EQ (true, (EqualityComparableWith<int, int>));
  275. EXPECT_EQ (true, (EqualityComparableWith<int, bool>));
  276. EXPECT_EQ (false, (EqualityComparableWith<Empty, Empty>));
  277. EXPECT_EQ (false, (EqualityComparableWith<int, Empty>));
  278. EXPECT_EQ (true, (EqualityComparableWith<A, A>));
  279. EXPECT_EQ (false, (EqualityComparableWith<A, B>));
  280. // StrictTotallyOrdered
  281. EXPECT_EQ (false, (StrictTotallyOrdered<void>));
  282. EXPECT_EQ (true, (StrictTotallyOrdered<bool>));
  283. EXPECT_EQ (true, (StrictTotallyOrdered<int>));
  284. EXPECT_EQ (true, (StrictTotallyOrdered<double>));
  285. EXPECT_EQ (false, (StrictTotallyOrdered<Empty>));
  286. EXPECT_EQ (false, (StrictTotallyOrdered<A>));
  287. EXPECT_EQ (true, (StrictTotallyOrdered<B>));
  288. // StrictTotallyOrderedWith
  289. EXPECT_EQ (false, (StrictTotallyOrderedWith<void, void>));
  290. EXPECT_EQ (false, (StrictTotallyOrderedWith<int, void>));
  291. EXPECT_EQ (true, (StrictTotallyOrderedWith<bool, bool>));
  292. EXPECT_EQ (true, (StrictTotallyOrderedWith<int, double>));
  293. EXPECT_EQ (false, (StrictTotallyOrderedWith<int, Empty>));
  294. EXPECT_EQ (false, (StrictTotallyOrderedWith<Base, Derived1>));
  295. EXPECT_EQ (false, (StrictTotallyOrderedWith<A, A>));
  296. EXPECT_EQ (true, (StrictTotallyOrderedWith<B, B>));
  297. EXPECT_EQ (false, (StrictTotallyOrderedWith<A, B>));
  298. }
  299. TEST(TConcepts, Types) {
  300. // Semiregular
  301. EXPECT_EQ (false, (Semiregular<void>));
  302. EXPECT_EQ (true, (Semiregular<int>));
  303. EXPECT_EQ (true, (Semiregular<Empty>));
  304. EXPECT_EQ (false, (Semiregular<HaveOnlyMove>));
  305. EXPECT_EQ (false, (Semiregular<HaveOnlyCopy>));
  306. EXPECT_EQ (false, (Semiregular<HaveCopyAndMove>));
  307. EXPECT_EQ (false, (Semiregular<A>));
  308. EXPECT_EQ (true, (Semiregular<B>));
  309. // Regular
  310. EXPECT_EQ (false, (Regular<void>));
  311. EXPECT_EQ (true, (Regular<int>));
  312. EXPECT_EQ (true, (Regular<int*>));
  313. EXPECT_EQ (false, (Regular<Empty>));
  314. EXPECT_EQ (false, (Regular<HaveOnlyMove>));
  315. EXPECT_EQ (false, (Regular<HaveOnlyCopy>));
  316. EXPECT_EQ (false, (Regular<HaveCopyAndMove>));
  317. EXPECT_EQ (false, (Regular<A>));
  318. EXPECT_EQ (true, (Regular<B>));
  319. // Scalar
  320. EXPECT_EQ (false, (Scalar<void>));
  321. EXPECT_EQ (true, (Scalar<int>));
  322. EXPECT_EQ (true, (Scalar<long*>));
  323. EXPECT_EQ (false, (Scalar<A>));
  324. EXPECT_EQ (false, (Scalar<B>));
  325. // Arithmetic
  326. EXPECT_EQ (false, (Arithmetic<void>));
  327. EXPECT_EQ (true, (Arithmetic<int>));
  328. EXPECT_EQ (false, (Arithmetic<long*>));
  329. EXPECT_EQ (false, (Arithmetic<A>));
  330. EXPECT_EQ (false, (Arithmetic<B>));
  331. // FloatingPoint
  332. EXPECT_EQ (false, (FloatingPoint<void>));
  333. EXPECT_EQ (true, (FloatingPoint<float>));
  334. EXPECT_EQ (true, (FloatingPoint<double>));
  335. EXPECT_EQ (false, (FloatingPoint<int>));
  336. EXPECT_EQ (false, (FloatingPoint<float*>));
  337. EXPECT_EQ (false, (FloatingPoint<A>));
  338. EXPECT_EQ (false, (FloatingPoint<B>));
  339. }
  340. struct Inv {
  341. void operator() (int) { };
  342. void operator() () { };
  343. };
  344. struct Pred {
  345. bool operator () (int) { return true; }
  346. bool operator () (int, int) { return true; }
  347. };
  348. TEST(TConcepts, Callable) {
  349. EXPECT_EQ (true, (Invocable<Inv, int>));
  350. EXPECT_EQ (true, (Invocable<Inv>));
  351. EXPECT_EQ (true, (Invocable<Inv, double>));
  352. EXPECT_EQ (false, (Invocable<Inv, Empty>));
  353. EXPECT_EQ (true, (RegularInvocable<Inv, int>));
  354. EXPECT_EQ (false, (Predicate<Inv, int>));
  355. EXPECT_EQ (true, (Predicate<Pred, int>));
  356. EXPECT_EQ (false, (Predicate<Pred, Empty>));
  357. EXPECT_EQ (true, (Relation<Pred, int, int>));
  358. EXPECT_EQ (true, (Relation<Pred, int, double>));
  359. EXPECT_EQ (false, (Relation<Pred, Empty, int>));
  360. EXPECT_EQ (true, (StrictWeakOrder<Pred, int, int>));
  361. EXPECT_EQ (false, (StrictWeakOrder<Pred, int, Empty>));
  362. }
  363. struct Incr {
  364. Incr& operator++() { return *this; }
  365. Incr operator++(int) { return *this; }
  366. };
  367. int type_printer (int* i) { return *i; }
  368. TEST(TConcepts, Iterators) {
  369. // type_printer(detail::try_ppI<Incr&>{});
  370. // type_printer(detail::try_Ipp<Incr&>{});
  371. // type_printer(meta::detected_t<detail::try_ppI, int>{});
  372. EXPECT_EQ (true, (WeaklyIncrementable<int>));
  373. EXPECT_EQ (false, (WeaklyIncrementable<void>));
  374. EXPECT_EQ (false, (WeaklyIncrementable<meta::nil_>));
  375. EXPECT_EQ (true, (WeaklyIncrementable<Incr>));
  376. EXPECT_EQ (false, (WeaklyIncrementable<Incr&>));
  377. }
  378. }