assign_value.pass.cpp 7.5 KB

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