const_optional_U.pass.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. //===----------------------------------------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. // UNSUPPORTED: c++98, c++03, c++11, c++14
  9. // <optional>
  10. // From LWG2451:
  11. // template<class U>
  12. // optional<T>& operator=(const optional<U>& rhs);
  13. #include <optional>
  14. #include <type_traits>
  15. #include <cassert>
  16. #include "test_macros.h"
  17. #include "archetypes.h"
  18. using std::optional;
  19. struct X
  20. {
  21. static bool throw_now;
  22. X() = default;
  23. X(int)
  24. {
  25. if (throw_now)
  26. TEST_THROW(6);
  27. }
  28. };
  29. bool X::throw_now = false;
  30. struct Y1
  31. {
  32. Y1() = default;
  33. Y1(const int&) {}
  34. Y1& operator=(const Y1&) = delete;
  35. };
  36. struct Y2
  37. {
  38. Y2() = default;
  39. Y2(const int&) = delete;
  40. Y2& operator=(const int&) { return *this; }
  41. };
  42. template <class T>
  43. struct AssignableFrom {
  44. static int type_constructed;
  45. static int type_assigned;
  46. static int int_constructed;
  47. static int int_assigned;
  48. static void reset() {
  49. type_constructed = int_constructed = 0;
  50. type_assigned = int_assigned = 0;
  51. }
  52. AssignableFrom() = default;
  53. explicit AssignableFrom(T) { ++type_constructed; }
  54. AssignableFrom& operator=(T) { ++type_assigned; return *this; }
  55. AssignableFrom(int) { ++int_constructed; }
  56. AssignableFrom& operator=(int) { ++int_assigned; return *this; }
  57. private:
  58. AssignableFrom(AssignableFrom const&) = delete;
  59. AssignableFrom& operator=(AssignableFrom const&) = delete;
  60. };
  61. template <class T> int AssignableFrom<T>::type_constructed = 0;
  62. template <class T> int AssignableFrom<T>::type_assigned = 0;
  63. template <class T> int AssignableFrom<T>::int_constructed = 0;
  64. template <class T> int AssignableFrom<T>::int_assigned = 0;
  65. void test_with_test_type() {
  66. using T = TestTypes::TestType;
  67. T::reset();
  68. { // non-empty to empty
  69. T::reset_constructors();
  70. optional<T> opt;
  71. const optional<int> other(42);
  72. opt = other;
  73. assert(T::alive == 1);
  74. assert(T::constructed == 1);
  75. assert(T::value_constructed == 1);
  76. assert(T::assigned == 0);
  77. assert(T::destroyed == 0);
  78. assert(static_cast<bool>(other) == true);
  79. assert(*other == 42);
  80. assert(static_cast<bool>(opt) == true);
  81. assert(*opt == T(42));
  82. }
  83. assert(T::alive == 0);
  84. { // non-empty to non-empty
  85. optional<T> opt(101);
  86. const optional<int> other(42);
  87. T::reset_constructors();
  88. opt = other;
  89. assert(T::alive == 1);
  90. assert(T::constructed == 0);
  91. assert(T::assigned == 1);
  92. assert(T::value_assigned == 1);
  93. assert(T::destroyed == 0);
  94. assert(static_cast<bool>(other) == true);
  95. assert(*other == 42);
  96. assert(static_cast<bool>(opt) == true);
  97. assert(*opt == T(42));
  98. }
  99. assert(T::alive == 0);
  100. { // empty to non-empty
  101. optional<T> opt(101);
  102. const optional<int> other;
  103. T::reset_constructors();
  104. opt = other;
  105. assert(T::alive == 0);
  106. assert(T::constructed == 0);
  107. assert(T::assigned == 0);
  108. assert(T::destroyed == 1);
  109. assert(static_cast<bool>(other) == false);
  110. assert(static_cast<bool>(opt) == false);
  111. }
  112. assert(T::alive == 0);
  113. { // empty to empty
  114. optional<T> opt;
  115. const optional<int> other;
  116. T::reset_constructors();
  117. opt = other;
  118. assert(T::alive == 0);
  119. assert(T::constructed == 0);
  120. assert(T::assigned == 0);
  121. assert(T::destroyed == 0);
  122. assert(static_cast<bool>(other) == false);
  123. assert(static_cast<bool>(opt) == false);
  124. }
  125. assert(T::alive == 0);
  126. }
  127. void test_ambigious_assign() {
  128. using OptInt = std::optional<int>;
  129. {
  130. using T = AssignableFrom<OptInt const&>;
  131. const OptInt a(42);
  132. T::reset();
  133. {
  134. std::optional<T> t;
  135. t = a;
  136. assert(T::type_constructed == 1);
  137. assert(T::type_assigned == 0);
  138. assert(T::int_constructed == 0);
  139. assert(T::int_assigned == 0);
  140. }
  141. T::reset();
  142. {
  143. std::optional<T> t(42);
  144. t = a;
  145. assert(T::type_constructed == 0);
  146. assert(T::type_assigned == 1);
  147. assert(T::int_constructed == 1);
  148. assert(T::int_assigned == 0);
  149. }
  150. T::reset();
  151. {
  152. std::optional<T> t(42);
  153. t = std::move(a);
  154. assert(T::type_constructed == 0);
  155. assert(T::type_assigned == 1);
  156. assert(T::int_constructed == 1);
  157. assert(T::int_assigned == 0);
  158. }
  159. }
  160. {
  161. using T = AssignableFrom<OptInt&>;
  162. OptInt a(42);
  163. T::reset();
  164. {
  165. std::optional<T> t;
  166. t = a;
  167. assert(T::type_constructed == 1);
  168. assert(T::type_assigned == 0);
  169. assert(T::int_constructed == 0);
  170. assert(T::int_assigned == 0);
  171. }
  172. {
  173. using Opt = std::optional<T>;
  174. static_assert(!std::is_assignable_v<Opt&, OptInt const&>, "");
  175. }
  176. }
  177. }
  178. int main(int, char**)
  179. {
  180. test_with_test_type();
  181. test_ambigious_assign();
  182. {
  183. optional<int> opt;
  184. constexpr optional<short> opt2;
  185. opt = opt2;
  186. static_assert(static_cast<bool>(opt2) == false, "");
  187. assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
  188. }
  189. {
  190. optional<int> opt;
  191. constexpr optional<short> opt2(short{2});
  192. opt = opt2;
  193. static_assert(static_cast<bool>(opt2) == true, "");
  194. static_assert(*opt2 == 2, "");
  195. assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
  196. assert(*opt == *opt2);
  197. }
  198. {
  199. optional<int> opt(3);
  200. constexpr optional<short> opt2;
  201. opt = opt2;
  202. static_assert(static_cast<bool>(opt2) == false, "");
  203. assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
  204. }
  205. {
  206. optional<int> opt(3);
  207. constexpr optional<short> opt2(short{2});
  208. opt = opt2;
  209. static_assert(static_cast<bool>(opt2) == true, "");
  210. static_assert(*opt2 == 2, "");
  211. assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
  212. assert(*opt == *opt2);
  213. }
  214. #ifndef TEST_HAS_NO_EXCEPTIONS
  215. {
  216. optional<X> opt;
  217. optional<int> opt2(42);
  218. assert(static_cast<bool>(opt2) == true);
  219. try
  220. {
  221. X::throw_now = true;
  222. opt = opt2;
  223. assert(false);
  224. }
  225. catch (int i)
  226. {
  227. assert(i == 6);
  228. assert(static_cast<bool>(opt) == false);
  229. }
  230. }
  231. #endif
  232. return 0;
  233. }