bases.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. #include <catch2/catch.hpp>
  2. #include <tl/expected.hpp>
  3. #include <string>
  4. // Old versions of GCC don't have the correct trait names. Could fix them up if needs be.
  5. #if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && \
  6. !defined(__clang__))
  7. // nothing for now
  8. #else
  9. TEST_CASE("Triviality", "[bases.triviality]") {
  10. REQUIRE(std::is_trivially_copy_constructible<tl::expected<int,int>>::value);
  11. REQUIRE(std::is_trivially_copy_assignable<tl::expected<int,int>>::value);
  12. REQUIRE(std::is_trivially_move_constructible<tl::expected<int,int>>::value);
  13. REQUIRE(std::is_trivially_move_assignable<tl::expected<int,int>>::value);
  14. REQUIRE(std::is_trivially_destructible<tl::expected<int,int>>::value);
  15. REQUIRE(std::is_trivially_copy_constructible<tl::expected<void,int>>::value);
  16. REQUIRE(std::is_trivially_move_constructible<tl::expected<void,int>>::value);
  17. REQUIRE(std::is_trivially_destructible<tl::expected<void,int>>::value);
  18. {
  19. struct T {
  20. T(const T&) = default;
  21. T(T&&) = default;
  22. T& operator=(const T&) = default;
  23. T& operator=(T&&) = default;
  24. ~T() = default;
  25. };
  26. REQUIRE(std::is_trivially_copy_constructible<tl::expected<T,int>>::value);
  27. REQUIRE(std::is_trivially_copy_assignable<tl::expected<T,int>>::value);
  28. REQUIRE(std::is_trivially_move_constructible<tl::expected<T,int>>::value);
  29. REQUIRE(std::is_trivially_move_assignable<tl::expected<T,int>>::value);
  30. REQUIRE(std::is_trivially_destructible<tl::expected<T,int>>::value);
  31. }
  32. {
  33. struct T {
  34. T(const T&){}
  35. T(T&&) {}
  36. T& operator=(const T&) { return *this; }
  37. T& operator=(T&&) { return *this; }
  38. ~T(){}
  39. };
  40. REQUIRE(!std::is_trivially_copy_constructible<tl::expected<T,int>>::value);
  41. REQUIRE(!std::is_trivially_copy_assignable<tl::expected<T,int>>::value);
  42. REQUIRE(!std::is_trivially_move_constructible<tl::expected<T,int>>::value);
  43. REQUIRE(!std::is_trivially_move_assignable<tl::expected<T,int>>::value);
  44. REQUIRE(!std::is_trivially_destructible<tl::expected<T,int>>::value);
  45. }
  46. }
  47. TEST_CASE("Deletion", "[bases.deletion]") {
  48. REQUIRE(std::is_copy_constructible<tl::expected<int,int>>::value);
  49. REQUIRE(std::is_copy_assignable<tl::expected<int,int>>::value);
  50. REQUIRE(std::is_move_constructible<tl::expected<int,int>>::value);
  51. REQUIRE(std::is_move_assignable<tl::expected<int,int>>::value);
  52. REQUIRE(std::is_destructible<tl::expected<int,int>>::value);
  53. {
  54. struct T {
  55. T()=default;
  56. };
  57. REQUIRE(std::is_default_constructible<tl::expected<T,int>>::value);
  58. }
  59. {
  60. struct T {
  61. T(int){}
  62. };
  63. REQUIRE(!std::is_default_constructible<tl::expected<T,int>>::value);
  64. }
  65. {
  66. struct T {
  67. T(const T&) = default;
  68. T(T&&) = default;
  69. T& operator=(const T&) = default;
  70. T& operator=(T&&) = default;
  71. ~T() = default;
  72. };
  73. REQUIRE(std::is_copy_constructible<tl::expected<T,int>>::value);
  74. REQUIRE(std::is_copy_assignable<tl::expected<T,int>>::value);
  75. REQUIRE(std::is_move_constructible<tl::expected<T,int>>::value);
  76. REQUIRE(std::is_move_assignable<tl::expected<T,int>>::value);
  77. REQUIRE(std::is_destructible<tl::expected<T,int>>::value);
  78. }
  79. {
  80. struct T {
  81. T(const T&)=delete;
  82. T(T&&)=delete;
  83. T& operator=(const T&)=delete;
  84. T& operator=(T&&)=delete;
  85. };
  86. REQUIRE(!std::is_copy_constructible<tl::expected<T,int>>::value);
  87. REQUIRE(!std::is_copy_assignable<tl::expected<T,int>>::value);
  88. REQUIRE(!std::is_move_constructible<tl::expected<T,int>>::value);
  89. REQUIRE(!std::is_move_assignable<tl::expected<T,int>>::value);
  90. }
  91. {
  92. struct T {
  93. T(const T&)=delete;
  94. T(T&&)=default;
  95. T& operator=(const T&)=delete;
  96. T& operator=(T&&)=default;
  97. };
  98. REQUIRE(!std::is_copy_constructible<tl::expected<T,int>>::value);
  99. REQUIRE(!std::is_copy_assignable<tl::expected<T,int>>::value);
  100. REQUIRE(std::is_move_constructible<tl::expected<T,int>>::value);
  101. REQUIRE(std::is_move_assignable<tl::expected<T,int>>::value);
  102. }
  103. {
  104. struct T {
  105. T(const T&)=default;
  106. T(T&&)=delete;
  107. T& operator=(const T&)=default;
  108. T& operator=(T&&)=delete;
  109. };
  110. REQUIRE(std::is_copy_constructible<tl::expected<T,int>>::value);
  111. REQUIRE(std::is_copy_assignable<tl::expected<T,int>>::value);
  112. }
  113. {
  114. tl::expected<int, int> e;
  115. REQUIRE(std::is_default_constructible<decltype(e)>::value);
  116. REQUIRE(std::is_copy_constructible<decltype(e)>::value);
  117. REQUIRE(std::is_move_constructible<decltype(e)>::value);
  118. REQUIRE(std::is_copy_assignable<decltype(e)>::value);
  119. REQUIRE(std::is_move_assignable<decltype(e)>::value);
  120. REQUIRE(TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(decltype(e))::value);
  121. REQUIRE(TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(decltype(e))::value);
  122. # if !defined(TL_EXPECTED_GCC49)
  123. REQUIRE(std::is_trivially_move_constructible<decltype(e)>::value);
  124. REQUIRE(std::is_trivially_move_assignable<decltype(e)>::value);
  125. # endif
  126. }
  127. {
  128. tl::expected<int, std::string> e;
  129. REQUIRE(std::is_default_constructible<decltype(e)>::value);
  130. REQUIRE(std::is_copy_constructible<decltype(e)>::value);
  131. REQUIRE(std::is_move_constructible<decltype(e)>::value);
  132. REQUIRE(std::is_copy_assignable<decltype(e)>::value);
  133. REQUIRE(std::is_move_assignable<decltype(e)>::value);
  134. REQUIRE(!TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(decltype(e))::value);
  135. REQUIRE(!TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(decltype(e))::value);
  136. # if !defined(TL_EXPECTED_GCC49)
  137. REQUIRE(!std::is_trivially_move_constructible<decltype(e)>::value);
  138. REQUIRE(!std::is_trivially_move_assignable<decltype(e)>::value);
  139. # endif
  140. }
  141. {
  142. tl::expected<std::string, int> e;
  143. REQUIRE(std::is_default_constructible<decltype(e)>::value);
  144. REQUIRE(std::is_copy_constructible<decltype(e)>::value);
  145. REQUIRE(std::is_move_constructible<decltype(e)>::value);
  146. REQUIRE(std::is_copy_assignable<decltype(e)>::value);
  147. REQUIRE(std::is_move_assignable<decltype(e)>::value);
  148. REQUIRE(!TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(decltype(e))::value);
  149. REQUIRE(!TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(decltype(e))::value);
  150. # if !defined(TL_EXPECTED_GCC49)
  151. REQUIRE(!std::is_trivially_move_constructible<decltype(e)>::value);
  152. REQUIRE(!std::is_trivially_move_assignable<decltype(e)>::value);
  153. # endif
  154. }
  155. {
  156. tl::expected<std::string, std::string> e;
  157. REQUIRE(std::is_default_constructible<decltype(e)>::value);
  158. REQUIRE(std::is_copy_constructible<decltype(e)>::value);
  159. REQUIRE(std::is_move_constructible<decltype(e)>::value);
  160. REQUIRE(std::is_copy_assignable<decltype(e)>::value);
  161. REQUIRE(std::is_move_assignable<decltype(e)>::value);
  162. REQUIRE(!TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(decltype(e))::value);
  163. REQUIRE(!TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(decltype(e))::value);
  164. # if !defined(TL_EXPECTED_GCC49)
  165. REQUIRE(!std::is_trivially_move_constructible<decltype(e)>::value);
  166. REQUIRE(!std::is_trivially_move_assignable<decltype(e)>::value);
  167. # endif
  168. }
  169. }
  170. #endif