assign_value.pass.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  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. // template <class U> optional<T>& operator=(U&& v);
  11. #include <optional>
  12. #include <type_traits>
  13. #include <cassert>
  14. #include <memory>
  15. #include "test_macros.h"
  16. #include "archetypes.hpp"
  17. using std::optional;
  18. struct ThrowAssign {
  19. static int dtor_called;
  20. ThrowAssign() = default;
  21. ThrowAssign(int) { TEST_THROW(42); }
  22. ThrowAssign& operator=(int) {
  23. TEST_THROW(42);
  24. }
  25. ~ThrowAssign() { ++dtor_called; }
  26. };
  27. int ThrowAssign::dtor_called = 0;
  28. template <class T, class Arg = T, bool Expect = true>
  29. void assert_assignable() {
  30. static_assert(std::is_assignable<optional<T>&, Arg>::value == Expect, "");
  31. static_assert(!std::is_assignable<const optional<T>&, Arg>::value, "");
  32. }
  33. struct MismatchType {
  34. explicit MismatchType(int) {}
  35. explicit MismatchType(char*) {}
  36. explicit MismatchType(int*) = delete;
  37. MismatchType& operator=(int) { return *this; }
  38. MismatchType& operator=(int*) { return *this; }
  39. MismatchType& operator=(char*) = delete;
  40. };
  41. struct FromOptionalType {
  42. using Opt = std::optional<FromOptionalType>;
  43. FromOptionalType() = default;
  44. FromOptionalType(FromOptionalType const&) = delete;
  45. template <class Dummy = void>
  46. constexpr FromOptionalType(Opt&) { Dummy::BARK; }
  47. template <class Dummy = void>
  48. constexpr FromOptionalType& operator=(Opt&) { Dummy::BARK; return *this; }
  49. };
  50. void test_sfinae() {
  51. using I = TestTypes::TestType;
  52. using E = ExplicitTestTypes::TestType;
  53. assert_assignable<int>();
  54. assert_assignable<int, int&>();
  55. assert_assignable<int, int const&>();
  56. // Implicit test type
  57. assert_assignable<I, I const&>();
  58. assert_assignable<I, I&&>();
  59. assert_assignable<I, int>();
  60. assert_assignable<I, void*, false>();
  61. // Explicit test type
  62. assert_assignable<E, E const&>();
  63. assert_assignable<E, E &&>();
  64. assert_assignable<E, int>();
  65. assert_assignable<E, void*, false>();
  66. // Mismatch type
  67. assert_assignable<MismatchType, int>();
  68. assert_assignable<MismatchType, int*, false>();
  69. assert_assignable<MismatchType, char*, false>();
  70. // Type constructible from optional
  71. assert_assignable<FromOptionalType, std::optional<FromOptionalType>&, false>();
  72. }
  73. void test_with_test_type()
  74. {
  75. using T = TestTypes::TestType;
  76. T::reset();
  77. { // to empty
  78. optional<T> opt;
  79. opt = 3;
  80. assert(T::alive == 1);
  81. assert(T::constructed == 1);
  82. assert(T::value_constructed == 1);
  83. assert(T::assigned == 0);
  84. assert(T::destroyed == 0);
  85. assert(static_cast<bool>(opt) == true);
  86. assert(*opt == T(3));
  87. }
  88. { // to existing
  89. optional<T> opt(42);
  90. T::reset_constructors();
  91. opt = 3;
  92. assert(T::alive == 1);
  93. assert(T::constructed == 0);
  94. assert(T::assigned == 1);
  95. assert(T::value_assigned == 1);
  96. assert(T::destroyed == 0);
  97. assert(static_cast<bool>(opt) == true);
  98. assert(*opt == T(3));
  99. }
  100. { // test default argument
  101. optional<T> opt;
  102. T::reset_constructors();
  103. opt = {1, 2};
  104. assert(T::alive == 1);
  105. assert(T::constructed == 2);
  106. assert(T::value_constructed == 1);
  107. assert(T::move_constructed == 1);
  108. assert(T::assigned == 0);
  109. assert(T::destroyed == 1);
  110. assert(static_cast<bool>(opt) == true);
  111. assert(*opt == T(1, 2));
  112. }
  113. { // test default argument
  114. optional<T> opt(42);
  115. T::reset_constructors();
  116. opt = {1, 2};
  117. assert(T::alive == 1);
  118. assert(T::constructed == 1);
  119. assert(T::value_constructed == 1);
  120. assert(T::assigned == 1);
  121. assert(T::move_assigned == 1);
  122. assert(T::destroyed == 1);
  123. assert(static_cast<bool>(opt) == true);
  124. assert(*opt == T(1, 2));
  125. }
  126. { // test default argument
  127. optional<T> opt;
  128. T::reset_constructors();
  129. opt = {1};
  130. assert(T::alive == 1);
  131. assert(T::constructed == 2);
  132. assert(T::value_constructed == 1);
  133. assert(T::move_constructed == 1);
  134. assert(T::assigned == 0);
  135. assert(T::destroyed == 1);
  136. assert(static_cast<bool>(opt) == true);
  137. assert(*opt == T(1));
  138. }
  139. { // test default argument
  140. optional<T> opt(42);
  141. T::reset_constructors();
  142. opt = {};
  143. assert(static_cast<bool>(opt) == false);
  144. assert(T::alive == 0);
  145. assert(T::constructed == 0);
  146. assert(T::assigned == 0);
  147. assert(T::destroyed == 1);
  148. }
  149. }
  150. template <class T, class Value = int>
  151. void test_with_type() {
  152. { // to empty
  153. optional<T> opt;
  154. opt = Value(3);
  155. assert(static_cast<bool>(opt) == true);
  156. assert(*opt == T(3));
  157. }
  158. { // to existing
  159. optional<T> opt(Value(42));
  160. opt = Value(3);
  161. assert(static_cast<bool>(opt) == true);
  162. assert(*opt == T(3));
  163. }
  164. { // test const
  165. optional<T> opt(Value(42));
  166. const T t(Value(3));
  167. opt = t;
  168. assert(static_cast<bool>(opt) == true);
  169. assert(*opt == T(3));
  170. }
  171. { // test default argument
  172. optional<T> opt;
  173. opt = {Value(1)};
  174. assert(static_cast<bool>(opt) == true);
  175. assert(*opt == T(1));
  176. }
  177. { // test default argument
  178. optional<T> opt(Value(42));
  179. opt = {};
  180. assert(static_cast<bool>(opt) == false);
  181. }
  182. }
  183. template <class T>
  184. void test_with_type_multi() {
  185. test_with_type<T>();
  186. { // test default argument
  187. optional<T> opt;
  188. opt = {1, 2};
  189. assert(static_cast<bool>(opt) == true);
  190. assert(*opt == T(1, 2));
  191. }
  192. { // test default argument
  193. optional<T> opt(42);
  194. opt = {1, 2};
  195. assert(static_cast<bool>(opt) == true);
  196. assert(*opt == T(1, 2));
  197. }
  198. }
  199. void test_throws()
  200. {
  201. #ifndef TEST_HAS_NO_EXCEPTIONS
  202. using T = ThrowAssign;
  203. {
  204. optional<T> opt;
  205. try {
  206. opt = 42;
  207. assert(false);
  208. } catch (int) {}
  209. assert(static_cast<bool>(opt) == false);
  210. }
  211. assert(T::dtor_called == 0);
  212. {
  213. T::dtor_called = 0;
  214. optional<T> opt(std::in_place);
  215. try {
  216. opt = 42;
  217. assert(false);
  218. } catch (int) {}
  219. assert(static_cast<bool>(opt) == true);
  220. assert(T::dtor_called == 0);
  221. }
  222. assert(T::dtor_called == 1);
  223. #endif
  224. }
  225. enum MyEnum { Zero, One, Two, Three, FortyTwo = 42 };
  226. using Fn = void(*)();
  227. // https://bugs.llvm.org/show_bug.cgi?id=38638
  228. template <class T>
  229. constexpr T pr38638(T v)
  230. {
  231. std::optional<T> o;
  232. o = v;
  233. return *o + 2;
  234. }
  235. int main(int, char**)
  236. {
  237. test_sfinae();
  238. // Test with instrumented type
  239. test_with_test_type();
  240. // Test with various scalar types
  241. test_with_type<int>();
  242. test_with_type<MyEnum, MyEnum>();
  243. test_with_type<int, MyEnum>();
  244. test_with_type<Fn, Fn>();
  245. // Test types with multi argument constructors
  246. test_with_type_multi<ConstexprTestTypes::TestType>();
  247. test_with_type_multi<TrivialTestTypes::TestType>();
  248. // Test move only types
  249. {
  250. optional<std::unique_ptr<int>> opt;
  251. opt = std::unique_ptr<int>(new int(3));
  252. assert(static_cast<bool>(opt) == true);
  253. assert(**opt == 3);
  254. }
  255. {
  256. optional<std::unique_ptr<int>> opt(std::unique_ptr<int>(new int(2)));
  257. opt = std::unique_ptr<int>(new int(3));
  258. assert(static_cast<bool>(opt) == true);
  259. assert(**opt == 3);
  260. }
  261. test_throws();
  262. static_assert(pr38638(3) == 5, "");
  263. return 0;
  264. }